庆阳网站建设做标书的视频网站
news/
2025/9/30 17:55:44/
文章来源:
庆阳网站建设,做标书的视频网站,wordpress自动排版的编辑器,云开发环境httpModules 与 httpHandlers ASP.NET对请求处理的过程#xff1a;当请求一个*.aspx文件的时候#xff0c;这个请求会被inetinfo.exe进程截获#xff0c;它判断文件的后缀#xff08;aspx#xff09;之后#xff0c;将这个请求转交给ASPNET_ISAPI.dll#xff0c;ASPNET_…httpModules 与 httpHandlers ASP.NET对请求处理的过程当请求一个*.aspx文件的时候这个请求会被inetinfo.exe进程截获它判断文件的后缀aspx之后将这个请求转交给ASPNET_ISAPI.dllASPNET_ISAPI.dll会通过http管道Http PipeLine将请求发送给ASPNET_WP.exe进程在ASPNET_WP.exe进程中通过HttpRuntime来处理这个请求处理完毕将结果返回客户端。 inetinfo.exe进程是www服务的进程IIS服务和ASPNET_ISAPI.DLL都寄存在此进程中。 ASPNET_ISAPI.DLL是处理.aspx文件的win32组件。其实IIS服务器是只能识别.html文件的当IIS服务器发现被请求的文件是.aspx文件时IIS服务器将其交给aspnet_isapi.dll来处理。 aspnet_wp.exe进程ASP.NET框架进程提供.net运行的托管环境.net的CLR(公共语言运行时)就是寄存在此进程中。 ASP.NET Framework处理一个Http Request的流程 HttpRequest--inetinfo.exe--ASPNET_ISAPI.dll--ASPNET_WP.exe--HttpRuntime--HttpApplication Factory--HttpApplication--HttpModule--HttpHandler Factory--HttpHandler--HttpHandler.ProcessRequest()ASP.NET请求处理过程是基于管道模型的这个管道模型是由多个HttpModule和HttpHandler组成ASP.NET把http请求依次传递给管道中各个HttpModule最终被HttpHandler处理处理完成后再次经过管道中的HTTP模块把结果返回给客户端。我们可以在每个HttpModule中都可以干预请求的处理过程。 注意在http请求的处理过程中只能调用一个HttpHandler但可以调用多个HttpModule。 当请求到达HttpModule的时候系统还没有对这个请求真正处理但是我们可以在这个请求传递到处理中心HttpHandler之前附加一些其它信息或者截获的这个请求并作一些额外的工作也或者终止请求等。在HttpHandler处理完请求之后我们可以再在相应的HttpModule中把请求处理的结果进行再次加工返回客户端。 HttpModule HTTP模块是实现了System.Web.IhttpModule接口的类。 IHttpModule接口的声明 public interface IHttpModule { void Init (HttpApplication context); void Dispose (); } Init 方法系统初始化的时候自动调用这个方法允许HTTP模块向HttpApplication 对象中的事件注册自己的事件处理程序。 Dispose方法 这个方法给予HTTP模块在对象被垃圾收集之前执行清理的机会。此方法一般无需编写代码。 HTTP模块可以向System.Web.HttpApplication对象注册下面一系列事件 AcquireRequestState 当ASP.NET运行时准备好接收当前HTTP请求的对话状态的时候引发这个事件。 AuthenticateRequest 当ASP.NET 运行时准备验证用户身份的时候引发这个事件。 AuthorizeRequest 当ASP.NET运行时准备授权用户访问资源的时候引发这个事件。 BeginRequest 当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件。 Disposed 当ASP.NET完成HTTP请求的处理过程时引发这个事件。 EndRequest 把响应内容发送到客户端之前引发这个事件。 Error 在处理HTTP请求的过程中出现未处理异常的时候引发这个事件。 PostRequestHandlerExecute 在HTTP处理程序结束执行的时候引发这个事件。 PreRequestHandlerExecute 在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后ASP.NET 把该请求转发给适当的HTTP处理程序。 PreSendRequestContent 在ASP.NET把响应内容发送到客户端之前引发这个事件。这个事件允许我们在内容到达客户端之前改变响应内容。我们可以使用这个事件给页面输出添加用于所有页面的内容。例如通用菜单、头信息或脚信息。 PreSendRequestHeaders 在ASP.NET把HTTP响应头信息发送给客户端之前引发这个事件。在头信息到达客户端之前这个事件允许我们改变它的内容。我们可以使用这个事件在头信息中添加cookie和自定义数据。 ReleaseRequestState 当ASP.NET结束所搜有的请求处理程序执行的时候引发这个事件。 ResolveRequestCache 我们引发这个事件来决定是否可以使用从输出缓冲返回的内容来结束请求。这依赖于Web应用程序的输出缓冲时怎样设置的。 UpdateRequestCache 当ASP.NET完成了当前的HTTP请求的处理并且输出内容已经准备好添加给输出缓冲的时候引发这个事件。这依赖于Web应用程序的输出缓冲是如何设置的。 上面这么多的事件我们看起来可能会有些眼晕但没关系下面一步一步地看。 HttpModule生命周期示意图 下面是事件的触发顺序 BeginRequest和PreRequestHandlerExecute之间的事件是在服务器执行HttpHandler处理之前触发。 PostRequestHandlerExecute和PreSendRequestContent之间的事件是在服务器执行Handler处理之后触发。 下面我们看一下如何使用HttpModule来实现我们日常的应用 HttpModule通过在某些事件中注册把自己插入ASP.NET请求处理管道。当这些事件发生的时候ASP.NET调用对相应的HTTP模块这样该模块就能处理请求了。 1、向每个页面动态添加一些备注或说明性的文字 有的网站每一个页面都会弹出一个广告或在每个页面都以注释形式!-- --加入网站的版权信息。如果在每个页面教编写这样的JS代码的话对于大一点的网站这种JS代码的编写与维护可是一个很繁琐枯燥的工作。 有了HttpModule我们就可以很简单地解决这个问题了。HttpModule是客户端发出请求到客户端接收到服务器响应之间的一段必经之路。我们完全可以在服务器处理完请求之后并在向客户端发送响应文本之前这段时机把这段注释文字添加到页面文本之后。这样每一个页面请求都会被附加上这段注释文字。 这段代码究竟该在哪个事件里实现呢 PostRequestHandlerExecute和PreSendRequestContent之间的任何一个事件都可以但我比较喜欢在EndRequest事件里编写代码。 第一步创建一个类库ClassLibrary831。 第二步编写一个类实现IHttpModule接口 class TestModule:IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { } } 第三步在Init事件中注册EndRequest事件并实现事件处理方法 class TestModule:IHttpModule { public void Dispose(){} public void Init(HttpApplication context) { context.EndRequest new EventHandler(context_EndRequest); } void context_EndRequest(object sender, EventArgs e) { HttpApplication ha (HttpApplication)sender; ha.Response.Write(!--这是每个页面都会动态生成的文字。--grayworm--); } } 第四步在Web.Conofig中注册一下这个HttpModule模块 httpModules add nameTestModule typeClassLibrary831.TestModule,ClassLibrary831/add /httpModules name模块名称一般是类名 type有两部分组成前半部分是命名空间和类名组成的全名后半部分是程序集名称如果类是直接放在App_Code文件夹中那程序名称是App_Code。 这样在Web站点是添加该类库的引用后运行每个页面会发现其源文件中都会加入“!--这是每个页面都会动态生成的文字。--grayworm--”这句话。同样的方法你也可以在其中加入JS代码。 2、身份检查 大家在作登录时登录成功后一般要把用户名放在Session中保存在其它每一个页面的Page_Load事件中都检查Session中是否存在用户名如果不存在就说明用户未登录就不让其访问其中的内容。 在比较大的程序中这种做法实在是太笨拙因为你几乎要在每一个页面中都加入检测Session的代码导致难以开发和维护。下面我们看看如何使用HttpModule来减少我们的工作量 由于在这里我们要用到Session中的内容我们只能在AcquireRequestState和PreRequestHandlerExecute事件中编写代码因为在HttpModule中只有这两事件中可以访问Session。这里我们选择PreRequestHandlerExecute事件编写代码。 第一步创建一个类库ClassLibrary831。 第二步编写一个类实现IHttpModule接口 class TestModule:IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { } } 第三步在Init事件中注册PreRequestHandlerExecute事件并实现事件处理方法 class AuthenticModule:IHttpModule { public void Dispose(){} public void Init(HttpApplication context) { context.PreRequestHandlerExecute new EventHandler(context_PreRequestHandlerExecute); } void context_PreRequestHandlerExecute(object sender, EventArgs e) { HttpApplication ha (HttpApplication)sender; string path ha.Context.Request.Url.ToString(); int n path.ToLower().IndexOf(Login.aspx); if (n -1) //是否是登录页面不是登录页面的话则进入{} { if (ha.Context.Session[user] null) //是否Session中有用户名若是空的话转向登录页。 { ha.Context.Response.Redirect(Login.aspx?source path); } } } } 第四步在Login.aspx页面的“登录”按钮中加入下面代码 protected void Button1_Click(object sender, EventArgs e) { if(true) //判断用户名密码是否正确 { if (Request.QueryString[source] ! null) { string s Request.QueryString[source].ToLower().ToString(); //取出从哪个页面转来的 Session[user] txtUID.Text; Response.Redirect(s); //转到用户想去的页面 } else { Response.Redirect(main.aspx); //默认转向main.aspx } } } 第五步在Web.Conofig中注册一下这个HttpModule模块 httpModules add nameTestModule typeClassLibrary831.TestModule,ClassLibrary831/add /httpModules 3、多模块的操作 如果定义了多个HttpModule在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。 HttpHandler HttpHandler是HTTP请求的处理中心真正地对客户端请求的服务器页面做出编译和执行并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。 HttpHandler与HttpModule不同一旦定义了自己的HttpHandler类那么它对系统的HttpHandler的关系将是“覆盖”关系。 IHttpHandler接口声明 public interface IHttpHandler { bool IsReusable { get; } public void ProcessRequest(HttpContext context); //请求处理函数 } 示例把硬盘上的图片以流的方式写在页面上 class TestHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { FileStream fs new FileStream(context.Server.MapPath(worm.jpg), FileMode.Open); byte[] b new byte[fs.Length]; fs.Read(b, 0, (int)fs.Length); fs.Close(); context.Response.OutputStream.Write(b, 0, b.Length); } public bool IsReusable { get { return true; } } } Web.Config配置文件 httpHandlers add verb* path* typeClassLibrary831.TestHandler,ClassLibrary831/add /httpHandlers Verb属性指定了处理程序支持的HTTP动作。*支持所有的HTTP动作;“GET”支持Get操作;“POST”支持Post操作;“GET, POST”支持两种操作。 Path属性指定了需要调用处理程序的路径和文件名可以包含通配符。“*”、“*.aspx”、“showImage.aspx”、“test1.aspx,test2.aspx” Type属性用名字空间、类名称和程序集名称的组合形式指定处理程序或处理程序工厂的实际类型。ASP.NET运行时首先搜索bin目录中的DLL接着在GAC中搜索。 这样程序运行的效果是该网站的任何一个页面都会显示worm.jpg图片。如何只让一个页面default21.aspx执行HttpHandler中的ProcessRequest方法呢最简单的办法是在Web.Config文件中把path配置信息设为default21.aspx。 根据这个例子大家可以考虑一下如何编写“验证码”了。 IHttpHandler工厂 IHttpHandlerFactory的作用是对IHttpHandler进行管理。工厂的作用请见http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html IHttpHandlerFactory接口的声明 public interface IHttpHandlerFactory { IHttpHandler GetHandler (HttpContext context,string requestType,string url,string pathTranslated); void ReleaseHandler (IHttpHandler handler); } GetHandler返回实现IHttpHandler接口的类的实例ReleaseHandler使工厂可以重用现有的处理程序实例。 示例两个用IHttpHandlerFactory来实现对不同HttpHandler的调用。 有两个HttpHandler将图片显示在页面上的HttpHandler和生成验证码的Handler //将图片显示在页面上的Handler class TestHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { FileStream fs new FileStream(context.Server.MapPath(worm.jpg), FileMode.Open); byte[] b new byte[fs.Length]; fs.Read(b, 0, (int)fs.Length); fs.Close(); context.Response.OutputStream.Write(b, 0, b.Length); } public bool IsReusable { get { return true; } } } //生成验证码的Handler class CodeHandler:IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { Image b new Bitmap(50,20); Graphics g Graphics.FromImage(b); SolidBrush sb new SolidBrush(Color.White); Font f new Font(宋体, 12); string str ; Random r new Random(); for (int i 0; i 4; i) { str r.Next(10); } g.DrawString(str,f,sb,0,0); b.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); } } IHttpHandler工厂 class TestHandlerFactory : IHttpHandlerFactory { public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) { string fname url.Substring(url.IndexOf(/) 1); while (fname.IndexOf(/) ! -1) fname fname.Substring(fname.IndexOf(/) 1); string cname fname.Substring(0, fname.IndexOf(.)); string className ; className ClassLibrary831.CodeHandler; object h null; try { //h new TestHandler(); h Activator.CreateInstance(Type.GetType(className)); } catch (Exception e) { throw new HttpException(工厂不能为类型 cname 创建实例。, e); } return (IHttpHandler)h; } public void ReleaseHandler(IHttpHandler handler) { } }(车延禄) 配置文件 httpHandlers add verb* pathdefault21.aspx,default22.aspx typeClassLibrary831.TestHandlerFactory,ClassLibrary831/add /httpHandlers 这样TestHandlerFactory就会根据请求的不同页面执行不同的HttpHandler处理程序了。 HttpHandler使用会话 如果要在处理程序中使用Session那必须把该HttpHandler实现IRequiresSessionState接口,IRequiresSessionState接口是个空接口它没有抽象方法只是一个标记。此处就不作例子验证了 ASP.Net处理Http Request时使用Pipeline管道方式由各个HttpModule对请求进行处理然后到达 HttpHandlerHttpHandler处理完之后仍经过Pipeline中各个HttpModule的处理最后将HTML发送到客户端浏览 器中。 生命周期中涉及到几个非常重要的对象HttpHandler,HttpModule,IHttpHandlerFactory他们的执行(顺序)大致的执行过程是这样的client端发送页面请求被IIS的某个进程截获它根据申请的页 面后缀(.aspx)不同调用不同的页面处理程序(.asp-asp.dll; .aspx-ISAPI.dll).而页面处理程序在处理过程中则要经历HttpModule,HttpHandler的处理前者HttpModule用于页面处理前和处理后的一些事件的处理后者HttpHandler进行真正的页面的处理。如前所说HttpModule会在页面处理前和后对页面进行处理所以它不会影响真正的页面请求。通常用在给每个页面的头部或者尾部添加一些信息如版 权声明等.曾经见过一些免费的空间我们的页面上传上去后浏览的时候发现在每个页面的头部和尾部多了很多小广告....,如果理解了 HttpModule的原理要做这个就不是很难了~ IHttpModule与IHttpHandler的区别整理 1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件一些事件是在Handler之前运行的一些是在Handler之后运行的 2.对请求的处理上: IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求. IHttpHandler则属于挑食类型,只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到调用它. 3.IHttpHandler按照你的请求 生成响应的内容IHttpModule对请求进行预处理如验证、修改、过滤等等同时也可以对响应进行处理 ASP.Net系统本身配置有很多HttpHandler和HttpModule以处理aspx等.Net标准的页面文件以及这些页面文件中标 准的事件处理等。查看%System%/Microsoft.NET\Framework\v2.0.50727\CONFIG目录下的 web.config文件中的httpHandlers和httpModules节点可以看到这些配置。如果有兴趣可以使用Reflector查 看.Net系统中相关的类和方法了解.Net如何处理以及做了什么处理。 .Net也提供了一套机制来开发自定义的HttpHandler和 HttpModule均可以用于对HttpRequest的截取完成自定义的处理。 HttpModule 继承System.Web.IHttpModule接口实现自己的HttpModule类。必须要实现接口的两个方法Init和Dispose。在 Init中可以添加需要截取的事件Dispose用于资源的释放如果在Init中创建了自己的资源对象请在Dispose中进行释放。 namespace MyModule{public class MyHttpModule : IHttpModule{ public MyHttpModule() { } //Init方法用来注册HttpApplication 事件。 public void Init(HttpApplication r_objApplication) { r_objApplication.BeginRequest new EventHandler(this.BeginRequest); } public void Dispose() { } private void BeginRequest(object r_objSender, EventArgs r_objEventArgs) { HttpApplication objApp (HttpApplication)r_objSender; objApp.Response.Write(您请求的URL为 objApp.Request.Path); }} } 将编译的dll文件拷贝到web项目的bin目录下在web项目的web.config文件system.web节点中配置 这样就将自定义的HttpModule类MyHttpModule插入到了当前web的HttpModule的Pipeline中。 HttpModule主要功能是对Application的各个事件进行截取在这些事件中完成自己的处理。其实如果自己开发一些项目直接在 Global.asax中处理已经足够了。如果是开发一个Framework或者是某些方面的组件需要在事件中添加处理开发自定义的 HttpModule可以避免使用Framework或者组件时还得手工在Global.asax中添加代码。 目前想到的开发自定义HttpModule的用途有全局的身份/权限验证、自定义网站访问/操作日志的记录、处于管理/调试等目的对站点进行监控追踪 等。当然如果是结合自定义的HttpHandler进行Framework的开发HttpModule可以用于其它的一些特殊的处理。 httpModules add nametest typeMyHttpModuleTest.MyHttpModule,MyHttpModule/ /httpModules 注意要区分大小写因为web.config作为一个XML文件是大小写敏感的。“typeMyHttpModuleTest.MyHttpModule,MyHttpModule”告诉我们 系统将会将http request请求交给位于MyHttpModule.dll文件中的MyHttpModuleTest.MyHttpModule类去处理。 HttpHandler是完全的对Http Request的截取。 首先继承System.Web.IHttpHandler接口实现自己的HttpHandler类。必须要实现接口的ProcessRequest方 法和IsReusable属性。ProcessRequest方法中完成对每个Http Request的处理发送处理结果的HTML到输出缓存中。IsReusable属性被.Net Framework调用用以确定这个HttpHandler的实例是否可以被重用于同类型其它的Request处理。 如果你在自己的HttpHandler类中需要读取或者是写Session值需要再继承一个接口IRequiresSessionState。这个接 口没有任何方法只是一个标记接口。继承这个接口之后就可以在自己的HttpHandler中访问Session可以在Session中写入值。namespace MyHandler{public class MyHttpHandler : IHttpHandler, IRequiresSessionState{ public MyHttpHandler() {} public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { HttpResponse objResponse context.Response ; objResponse.Write( This request is handled by MyHttpHandler); }}} 把编译的dll文件拷贝到web项目的bin目录下。 接下来这样来测试一下MyHttpHandler。我们为IIS配置一个以.cc为后缀名的文件类型用我们写的MyHttpHandler来处理。 首先在IIS站点的Configuration配置里面添加一个对.cc后缀名处理的Application Extention Mapping项。 然后在web项目的web.config节点节点中配置 MyHttpHandler, MyHandler/ verb属性配置这个HttpHandler处理那些HTTP方法例如GET、POST等如果是处理所有方法就用*。path属性配置HttpHandler对哪些文件进行处理例如可以是myfile.cc如果是处理所有的.cc文件就用*.cc。 这样这个站点上所有.cc类型文件的访问都由MyHttpHandler处理。使用http://localhost/站点虚拟目录/a.cc访问测试站点可以看到测试效果。当然a.cc这个文件在Web服务器上是并不存在的。 对HttpHandler的使用比较典型的有.Net的Web MVC开源项目Maverick。Maverick使用一个Dispatcher类对所有的Http Request进行截取他以.m作为后缀名向Web服务器提交请求在Dispatcher中将.m的后缀去掉提取Command Name然后以这个command name从配置文件中加载处理的flow形成一个chain依次对chain上的各个command和view进行处理对各个command和 view的处理结果可能会在chain中选择不同的处理分支每个处理的Step中将处理结果的HTML写入Response的缓存中进行输出。 总体来说Maverick的框架架构概念很不错但也存在明显的缺陷以后有时间再详细的写写它的架构和需要改进之处。 总之将HttpModule、HttpHandler以及使用Ajax等将客户端进行封装结合起来能够给web项目的开发带来非常大的改善空间。 Asp.Net HttpHandler实现URL重写的我们经常看到很多网站访问文章的时候才用的是***.html 或***.shtml (如本blog的日志访问效果)其时这写文件在服务器上不存在的那为什么会出现这样的效果呢是因为Web服务器上对URL执行了重写把访问的 URL根据特定的格式重写成内部访问页面来实现的它的好处是便于用户理解同时搜索引擎也能更好地收入你的网站当然其它的好处也很多这里不做一一介 绍了。 本文所讲的是使用Asp.Net中的HttpHandler实现URL重写的它所实现的原理请看这里本程序可以处理任何Url因为我在程序中使用了URL过虑只有访问文件名是数字的才进行处理并指在内部执行一个新的页面并输出数据代码如下public void ProcessRequest(HttpContext Context){ try { //申明Request HttpRequest Request Context.Request; //取来路Url的绝对路径 string Url Request.Url.AbsolutePath; //取访问的Web文件的开始字符间隔数int RegStart Url.LastIndexOf(/) 1; //申明一个确定Web文件名是否全是数字Regex Reg new Regex(\d); //用正则表达式进行匹配 if (Reg.IsMatch(Url, RegStart)) { // 如果web文件名是数字则判定是查询相关文章执行指定页面 Context.Server.Execute(~/PermaLink.aspx?id Reg.Match(Url, RegStart).Value); } }catch{ Context.Response.Redirect(Context.Request.Url.ToString()); }}当然你首先要做的是先建一个类并继承自IHttpHandler然后把这段代码拷入并编译。在Web项目中若要使用此功能需要在web.config里面加上如下语句httpHandlers add verb* path*.shtml typeHttpHandle.UrlRewrite //httpHandlers同时还要在IIS中对Web项目进行配置在Web项目的属性中在主目录选项卡里把执行权限改为脚本和可执行文件然后打开配置在应用程序扩展里加上需重写的文件格式的扩展好了成事具备只欠运行了。 转载于:https://www.cnblogs.com/cmblogs/p/4028621.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923111.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!