ASP.NET 中Http处理流程与 HttpModule,HttpHandler学习之初步认知
2011-12-14 17:24
791 查看
本文只是对HttpModule和HttpHandler做最初步的了解。非菜鸟级别人士可直接无视。
ASP.NET 中Http的请求流程
1. 用户发出的客户端请求达到服务器后,会被服务端的inetinfo.exe 进程捕获,该进程将该http请求转交给asp.net_isapi.dll进程,然后通过http pipeline 管道(具体这是什么东西我也不清楚)传送给aspnet_wp.exe进程来处理。接下来就到了.net framework的httpruntime处理中心,处理完毕后,就发送给用户的浏览器。
2. 当http请求传送给httpruntime 的时候,首先会进入一个叫做HttpApplication Factory的容器之中,从这个名字上很容易看出是一个工厂,该工厂产生一个HttpApplication的实例,该实例保存有该请求的所有信息。然后,http请求进入HttpModule容器之中,然后进入HttpHandlerFactory中,调用相应的HttpHandler,执行其ProcessRequest方法,完成整个请求的处理。其中httpHandler是真正的请求处理中心。Httpmodule只是在该处理中心做处理之前对其进行一些额外的处理,筛选等等。
3. 大体的流程如下所示
HttpRequest------ inetinfo.exe--- aspnet_isapi.dll ---- http pipeline --aspnet_wp.exe ---http runtime----Http Application ---Http Application ---HttpModule---HttpHandler Factory ---HttpHandler -----HttpHandler.Process Request()
以上内容大多取自【我也想飞翔-tangself】的HttpModule的认识一文,大家可以 看原作: http://www.cnblogs.com/tangself/archive/2011/03/28/1998007.html
4. 执行ProcessRequest 的过程其实也就是整个ASP.NET page 页面的生命周期。
ASP.NET 的Page类实现了IHttpHandler,而我们每一个页面都是继承与Page的,那么也就是说每一个页面都是一个HttpHandler,这个Handler就会处理当前页面的请求。看来,应该是默认将该Handler和该页面路径匹配起来。这个我没有考证,只是我的推测。
ProcessRequest 首先会调用this.FrameworkInitialize(); 以构建控件树。然后预初始化OnPreInit,然后 调用PerformPreInit()完成预初始化,然后开始初始化Init(),注意执行初始化的时候 已经执行了TraceViewState ,已经开始对数据进行了跟踪,如果数据成为dirty数据,则会被存储到statebag中。具体什么时候开启的,我现在还不太清楚。接下来,如果是回传,则会加载控件的页面视图状态,处理回传数据(ProcessPostData) ,如果是第一加载,则会跳过这一部分。随后执行预加载操作OnPreLoad,然后执行OnLoad(LoadRecursive)。如果是回传,会发送回传变化通知,处理回传事件方法RaisePostbackEvent。随后执行OnLoadCompleted
。接下来进入预呈现OReRender,保存个性化数据和视图状态(所谓的视图状态保存,在这个部分实际上就是调用SaveState,将原有的键值对数据保存到一个ArrayList中,序列化输出到页面上是之后的事情了)。然后执行呈现方法Render,随后页面加载完毕执行OnUnload操作。
更加详细可靠的内容大家可以移步这里
1. ASP.NET编程模型之ASP.NET页面生命周期图解 http://developer.51cto.com/art/200908/141235.htm
2. ASP.NET VIEW STATE 详解(讲的很详细,由浅入深,老外的。。。)
http://www.cnblogs.com/xianrongbin/articles/2240851.html
HttpModule初步接触
我们可以实现自己的HttpModule,只要继承IHttpModule即可。
IHttpModul接口如下
下面是我自己写的Module,实际上和 http://www.cnblogs.com/tangself/archive/2011/03/28/1998007.html差不多。。。
这个类我建在了AppCode中,所以默认没有名空间
然后在web.config的system.web节点下添加如下配置
建立hellomodule页面,访问,页面输出如下
可以看出请求该页面前先执行了该Module中的方法。然后才转交给了页面这个HttpHandler。如果没有这个页面,我们随便访问一个地址,那么就会资源未找到的错误。
我们在建立一个HttpModule跟原来的一样,只不过命名为HttpModule2,添加配置。
访问页面可以发现,整个请求过程中先经过了myHttpModule 处理,在经过了myHttpModule1的处理。
注:type字段填写的是该module的名空间.类名,这样,就可以通过反射的方式进行调用。其实这也就是以来注入吧。
接下来我们在大概看一下HttpHandler
HttpHandler初步接触
我们也可以实现自己的HttpHandler。只要继承IHttpHandler即可。
IHttpHandler定义如下
下边是我自己实现的HttpHandler
然后在配置文件中添加如下配置
然后在浏览器中访问HelloHandler,如下所示
我们也可以将该path对应一个aspx页面,当然这样就像是给这个路径指定了两个HttpHandler。新建一个HelloHandler.aspx页面,添加内容【 this is in page!!!!!!!!!!!】,然后添加web.Config的Handler配置,我们看看效果
看来page对应的Handler没有生效。。。。
HttpHandler和HttpModule小小总结
在回过头来想,最初那个Page Resource Not Fond 的错误,其实并不是 Page Not Found而是请求路径对应的HttpHandler并没有找到。例如我们在配置文件做如下配置
请求http://localhost:1684/HandlerStudy/my
输出内容如下
可以看出来,仍然先经过了连个Module的处理,服务器认为该路径对应是有资源的,并没有出现Page not found 的错误。然后,找到该路径所配置的HttpHandler 执行相应的ProcesRequest方法。
那么综合前边Asp.net 流程的分析,我们就不难得出 如下结论。
当Http 请求进入到HttpRuntime 时,首先会交由一个HttpModule的处理链一次处理,处理先后顺序和配置顺序一致(其实也应该是事件订阅的先后顺序),该HttpModule处理完毕后,HttpHandler Factory 会获取所有注入的HttpHandler,根据路径匹配出相应的Handler,利用反射生成相应Handler实例,调用相应ProcessRequest方法。
查看PageHandlerFactory 代码发现
应该基本上就是这样。
Ok,关于HttpHandler和HttpModule的初步学习就这么多。对其二者的使用还需要做进一步深入理解。还有就是Page 本身也是一个Handler,是在什么时候,又是如何注册到Handler Factory中的,这个问题也需要查一下。
ASP.NET 中Http的请求流程
1. 用户发出的客户端请求达到服务器后,会被服务端的inetinfo.exe 进程捕获,该进程将该http请求转交给asp.net_isapi.dll进程,然后通过http pipeline 管道(具体这是什么东西我也不清楚)传送给aspnet_wp.exe进程来处理。接下来就到了.net framework的httpruntime处理中心,处理完毕后,就发送给用户的浏览器。
2. 当http请求传送给httpruntime 的时候,首先会进入一个叫做HttpApplication Factory的容器之中,从这个名字上很容易看出是一个工厂,该工厂产生一个HttpApplication的实例,该实例保存有该请求的所有信息。然后,http请求进入HttpModule容器之中,然后进入HttpHandlerFactory中,调用相应的HttpHandler,执行其ProcessRequest方法,完成整个请求的处理。其中httpHandler是真正的请求处理中心。Httpmodule只是在该处理中心做处理之前对其进行一些额外的处理,筛选等等。
3. 大体的流程如下所示
HttpRequest------ inetinfo.exe--- aspnet_isapi.dll ---- http pipeline --aspnet_wp.exe ---http runtime----Http Application ---Http Application ---HttpModule---HttpHandler Factory ---HttpHandler -----HttpHandler.Process Request()
以上内容大多取自【我也想飞翔-tangself】的HttpModule的认识一文,大家可以 看原作: http://www.cnblogs.com/tangself/archive/2011/03/28/1998007.html
4. 执行ProcessRequest 的过程其实也就是整个ASP.NET page 页面的生命周期。
ASP.NET 的Page类实现了IHttpHandler,而我们每一个页面都是继承与Page的,那么也就是说每一个页面都是一个HttpHandler,这个Handler就会处理当前页面的请求。看来,应该是默认将该Handler和该页面路径匹配起来。这个我没有考证,只是我的推测。
ProcessRequest 首先会调用this.FrameworkInitialize(); 以构建控件树。然后预初始化OnPreInit,然后 调用PerformPreInit()完成预初始化,然后开始初始化Init(),注意执行初始化的时候 已经执行了TraceViewState ,已经开始对数据进行了跟踪,如果数据成为dirty数据,则会被存储到statebag中。具体什么时候开启的,我现在还不太清楚。接下来,如果是回传,则会加载控件的页面视图状态,处理回传数据(ProcessPostData) ,如果是第一加载,则会跳过这一部分。随后执行预加载操作OnPreLoad,然后执行OnLoad(LoadRecursive)。如果是回传,会发送回传变化通知,处理回传事件方法RaisePostbackEvent。随后执行OnLoadCompleted
。接下来进入预呈现OReRender,保存个性化数据和视图状态(所谓的视图状态保存,在这个部分实际上就是调用SaveState,将原有的键值对数据保存到一个ArrayList中,序列化输出到页面上是之后的事情了)。然后执行呈现方法Render,随后页面加载完毕执行OnUnload操作。
更加详细可靠的内容大家可以移步这里
1. ASP.NET编程模型之ASP.NET页面生命周期图解 http://developer.51cto.com/art/200908/141235.htm
2. ASP.NET VIEW STATE 详解(讲的很详细,由浅入深,老外的。。。)
http://www.cnblogs.com/xianrongbin/articles/2240851.html
HttpModule初步接触
我们可以实现自己的HttpModule,只要继承IHttpModule即可。
IHttpModul接口如下
Using System; Namespace System.Web { Public interface IHttpModule { // 销毁不再被HttpModule使用的资源 void Dispose(); // 初始化一个Module,为捕获HttpRequest做准备 void Init(HttpApplication context); {} }
下面是我自己写的Module,实际上和 http://www.cnblogs.com/tangself/archive/2011/03/28/1998007.html差不多。。。
public class MyHttpModule:IHttpModule { public MyHttpModule() { } public void Dispose() { } /// <summary> /// 准备初始化一个module,为截获httprequest做准备 /// </summary> /// <param name="context"></param> public void Init(HttpApplication context) { //通过两个事件订阅,加入自己的处理 context.BeginRequest+=new EventHandler(this.Application_BeginReqest); context.EndRequest+=new EventHandler(this.Application_EndReqest); } public void Application_BeginReqest(object sender,EventArgs e) { HttpApplication app = sender as HttpApplication; if(app!=null) { HttpContext context = app.Context; context.Response.Write("this is in module begin request "); } } public void Application_EndReqest(object sender, EventArgs e) { HttpApplication httpApp = sender as HttpApplication; if(httpApp!=null) { HttpContext context = httpApp.Context; context.Response.Write("this is in module end request"); } } }
这个类我建在了AppCode中,所以默认没有名空间
然后在web.config的system.web节点下添加如下配置
<httpModules> <add name="myHttpModule" type="MyHttpModule"/> </httpModules>
建立hellomodule页面,访问,页面输出如下
可以看出请求该页面前先执行了该Module中的方法。然后才转交给了页面这个HttpHandler。如果没有这个页面,我们随便访问一个地址,那么就会资源未找到的错误。
我们在建立一个HttpModule跟原来的一样,只不过命名为HttpModule2,添加配置。
<httpModules> <!--<先会经过这个链式的module>--> <add name="myHttpModule" type="MyHttpModule"/> <add name="myHttpModule2" type="MyHttpModule2"/> </httpModules>
访问页面可以发现,整个请求过程中先经过了myHttpModule 处理,在经过了myHttpModule1的处理。
注:type字段填写的是该module的名空间.类名,这样,就可以通过反射的方式进行调用。其实这也就是以来注入吧。
接下来我们在大概看一下HttpHandler
HttpHandler初步接触
我们也可以实现自己的HttpHandler。只要继承IHttpHandler即可。
IHttpHandler定义如下
public interface IHttpHandler { // Methods void ProcessRequest(HttpContext context); // Properties bool IsReusable { get; } }
下边是我自己实现的HttpHandler
public class MyHandler : IHttpHandler { public MyHandler() { } /// <summary> /// 根据webconfig中的httpHandler节点的path的配置,当访问该节点时,就会自动生成相应的type实例,调用该handler的 /// ProcessRequest方法 /// 所以,我们可以通过解析路径的方法,让路径对应一个handler中的某个方法,可以使用发射工厂 /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { Uri uri= context.Request.Url; context.Response.Write("<br/>"+uri.OriginalString); context.Response.Write("<br/><h1>Hello,this is my http handler</h1>"); } public bool IsReusable { get { return true; } } }
然后在配置文件中添加如下配置
<httpHandlers> <!--处理该aspx终点的输入请求为保留文件夹app_code中,程序集的定义可忽略 --> <add verb="*" path="HelloHandler" type="MyHandler"/> </httpHandlers>
然后在浏览器中访问HelloHandler,如下所示
我们也可以将该path对应一个aspx页面,当然这样就像是给这个路径指定了两个HttpHandler。新建一个HelloHandler.aspx页面,添加内容【 this is in page!!!!!!!!!!!】,然后添加web.Config的Handler配置,我们看看效果
看来page对应的Handler没有生效。。。。
HttpHandler和HttpModule小小总结
在回过头来想,最初那个Page Resource Not Fond 的错误,其实并不是 Page Not Found而是请求路径对应的HttpHandler并没有找到。例如我们在配置文件做如下配置
<httpHandlers>
<!--处理该aspx终点的输入请求为保留文件夹app_code中,程序集的定义可忽略 -->
<add verb="*" path="HelloHandler.aspx" type="MyHandler"/>
<add verb="*" path="my" type="MyHandler"/>
</httpHandlers>
<httpModules> <!--<先会经过这个链式的module>--> <add name="myHttpModule" type="MyHttpModule"/> <add name="myHttpModule2" type="MyHttpModule2"/> </httpModules>
请求http://localhost:1684/HandlerStudy/my
输出内容如下
可以看出来,仍然先经过了连个Module的处理,服务器认为该路径对应是有资源的,并没有出现Page not found 的错误。然后,找到该路径所配置的HttpHandler 执行相应的ProcesRequest方法。
那么综合前边Asp.net 流程的分析,我们就不难得出 如下结论。
当Http 请求进入到HttpRuntime 时,首先会交由一个HttpModule的处理链一次处理,处理先后顺序和配置顺序一致(其实也应该是事件订阅的先后顺序),该HttpModule处理完毕后,HttpHandler Factory 会获取所有注入的HttpHandler,根据路径匹配出相应的Handler,利用反射生成相应Handler实例,调用相应ProcessRequest方法。
查看PageHandlerFactory 代码发现
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) { return this.GetHandlerHelper(context, requestType, VirtualPath.CreateNonRelative(virtualPath), path); } private IHttpHandler GetHandlerHelper(HttpContext context, string requestType, VirtualPath virtualPath, string physicalPath) { Page page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page), context, true) as Page; if (page == null) { return null; } page.TemplateControlVirtualPath = virtualPath; return page; }
应该基本上就是这样。
Ok,关于HttpHandler和HttpModule的初步学习就这么多。对其二者的使用还需要做进一步深入理解。还有就是Page 本身也是一个Handler,是在什么时候,又是如何注册到Handler Factory中的,这个问题也需要查一下。
相关文章推荐
- ASP.NET 中Http处理流程与 HttpModule,HttpHandler学习之初步认知
- Asp.Net构架(Http请求处理流程)、(Http Handler 介绍)、(HttpModule 介绍)
- Asp.Net构架(Http请求处理流程)、Asp.Net 构架(Http Handler 介绍)、Asp.Net 构架(HttpModule 介绍)
- Asp.Net构架(Http请求处理流程)、Asp.Net 构架(Http Handler 介绍)、Asp.Net 构架(HttpModule 介绍)
- HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- Http 请求处理流程+Asp.Net 构架(Http Handler 介绍)
- ASP.NET的(HttpModule,HttpHandler) Asp.net处理模式
- HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。 .
- asp.net HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- 备忘一点ASP.net的东东:说说HttpHandler和HttpModule的区别及处理顺序
- ASP.NET处理用户请求的流程 IHttpModule , IHttpHandler 管道事件
- asp.net架构之请求处理过程:HttpModule,HttpHandler
- asp.net HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- Asp.Net构架(Http请求处理流程) - Part.2 Http Handler 介绍
- Asp.Net运行时对象生成过程以及HttpHandler和HttpModule的处理过程。
- HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- ASP.NET 管道事件与HttpModule, HttpHandler简单理解
- ASP.NET基础之HttpHandler学习