ASP.NET MVC学习(6)Asp.Net管道模型
序言
梳理出来每一个涉及到的对象
HttpRuntime
HttpApplication
HttpContext
HttpRequest
HttpResponse
HttpSessionState
HttpHandler
HttpModule
HttpHandler和HttpModule的区别
HttpModule的认识
HttpModule是向实现类提供模块初始化和处置事件。当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。
1、asp.net的HTTP请求处理过程
2、HttpModule工作原理
3、编写自己的HttpModule
要实现HttpModule,必须实现接口IHttpModule。下面是IHttpModule接口分析:
using System; using System.Web; namespace ClassLibrary1 { public class MyHttpModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Application_BeginRequest); context.EndRequest += new EventHandler(Application_EndRequest); } public void Application_BeginRequest(object sender, EventArgs e) { HttpApplication application = sender as HttpApplication; HttpContext context = application.Context; HttpResponse response = context.Response; response.Write("这是来自自定义HttpModule中有BeginRequest"); } public void Application_EndRequest(object sender, EventArgs e) { HttpApplication application = sender as HttpApplication; HttpContext context = application.Context; HttpResponse response = context.Response; response.Write("这是来自自定义HttpModule中有EndRequest"); } } }
web.config
<httpModules> <add name="myHttpModule" type="ClassLibrary1.MyHttpModule,ClassLibrary1"/> </httpModules>
Mvc动态注册HttpModule详解
我们知道HttpApplication在初始化的时候会初始化所有配置文件里注册的HttpModules,那么有一个疑问,能否初始化之前动态加载HttpModule,而不是只从Web.config里读取?
答案是肯定的, ASP.NET MVC3发布的时候提供了一个Microsoft.Web.Infrastructure.dll文件,这个文件就是提供了动态注册HttpModule的功能,那么它是如何以注册的呢?我们先去MVC3的源码看看该DLL的源代码。
怎么样,这个功能不错吧,不需要每次都在web.config里定义你的HttpModule咯,而且我们以后封装自己的类库就方便多了,不需要在网站程序集里指定代码去启动自己封装好的单独类库了,因为我们可以在自己的类库里直接使用这种方式实现自动注册的功能。
注册Httpmodule可以让我们使用HttpApplication对象中的处理管道事件
目前大家所熟知的应该有2种方式来使用HttpApplication对象中的处理管道事件
第一种是通过Global.asax全局文件
第二种是通过配置文件来注册httpmodule
DynamicModuleUtility.RegisterModule方法
通常通过 Web.config 文件的 <modules> 部分注册模块。然而,在运行时可通过 RegisterModule(Type) 方法注册模块。
不用配置 web.config 的 <httpModules> or <modules> 节点了!!!
Microsoft.Web.Infrastructure.dll与PreApplicationStartMethodAttribute属性
using System; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; [assembly: PreApplicationStartMethod(typeof(xxx.PreApplicationStartRegist), "PreStart")] namespace xxx { /// <summary> /// 动态注册 IHttpModel /// </summary> public class PreApplicationStartRegist { private static bool hasLoaded; static object _lock = new object(); public static void PreStart() { Console.WriteLine("PreApplicationStartRegist.PreStart() 执行..."); lock (_lock) { if (!hasLoaded) { hasLoaded = true; DynamicModuleUtility.RegisterModule(typeof(xxx.Service.PerformanceMonitorModule)); Console.WriteLine("PreApplicationStartRegist.PreStart() 注册 IHttpModle 成功!"); } } } } } namespace xxx.Service { /// <summary> /// http 管道,用于记录访问日志 /// </summary> public class PerformanceMonitorModule : IHttpModule { }
代码实现动态注册HttpMoudle
//通常通过 Web.config 文件的 <modules> 部分注册模块。然而,在运行时可通过 RegisterModule(Type) 方法注册模块。 DynamicModuleUtility.RegisterModule(typeof(CryptographyHttpModule));
RegisterModule 基础结构。动态注册 IHttpModule 模块。
WebActivatorEx
自定义HttpModule
class StartMethodCallingModule : IHttpModule { private static object _lock = new object(); private static int _initializedModuleCount; public void Init(HttpApplication context) { lock (_lock) { // Keep track of the number of modules initialized and // make sure we only call the post start methods once per app domain if (_initializedModuleCount++ == 0) { RunPostStartMethods(); } } } public void Dispose() { lock (_lock) { // Call the shutdown methods when the last module is disposed if (--_initializedModuleCount == 0) { RunShutdownMethods(); } } } }
WebActivator的实现原理详解
WebActivator提供了3种功能,允许我们分别在HttpApplication初始化之前,之后以及ShutDown的时候分别执行指定的代码,示例如下:
[assembly: WebActivator.PreApplicationStartMethod(typeof(A.InitClass1), "PreStart")] [assembly: WebActivator.PostApplicationStartMethod(typeof(A.InitClass1), "PostStart")] [assembly: WebActivator.ApplicationShutdownMethod(typeof(A.InitClass1), "ShutDown")]
//使用PreApplicationStartMethod注解的作用是在mvc应用启动之前执行操作 [assembly: PreApplicationStartMethod(typeof(FastExecutor.Base.Util.PluginUtil), "PreInitialize")]
HttpHandler和HttpModule的区别
HttpHandler与HttpModule的理解与应用
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中都可以干预请求的处理过程。
MvcHandler是如何接管请求的
我们能否自己来写一个自定义的HttpHandler通过Route动态注册进去,来实现我们自己的自定义扩展
https://www.cnblogs.com/TomXu/p/3756863.html
HttpContext
HttpContext.Current.Items用途
首先,我们看HttpContext.Current.Items的用途,它只作用于单独的一个用户请求(HttpContext.Current.Items valid for a single HTTPRequest)。
完成这个请求,服务器信息传回浏览器的时候,这个Item集合将丢失。而Session对象是针对用户的本次会话,也就是作用 于多个用户请求,在Session失效后才丢失其中的信息。
既然HttpContext.Current.Items的生命周期如此之短,那在什么情况下可以加以利用呢。
这里指出,HttpContext.Current.Items可以在HttpModule和HTTPHandler之间共享数据时使用,因为每次用户请求都要通过HTTP 运行时管道HttpModule 、HTTPHandler 。当你实现IHttpMoudle的方法来通过HttpMoudle向用户请求传递信息。
你可以用HttpContext.Current.Items 在不同请求页,不同的HttpModule中传输数据,但是一旦请求结束,数据回发,这个集合中的数据将自己丢失。
HttpContext.Current.Items.Add
资料
Asp.Net构架(Http请求处理流程) - Part.1
Asp.Net 构架(Http Handler 介绍) - Part.2
Asp.Net 构架(HttpModule 介绍) - Part.3
https://www.cnblogs.com/caoyc/p/6409062.html