Asp.net管道模型之(HttpModules 和 HttpHandler)

Posted loverwangshan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Asp.net管道模型之(HttpModules 和 HttpHandler)相关的知识,希望对你有一定的参考价值。

上一节我们从大概范围介绍了管道模型的整体流程,我们从其中知道管道最重要的两大组件为:HttpModules 跟 HttpHandler。今天我们着重来介绍一下这两大组件

一:asp.net处理管道

从请求进入ASP.NET工作者进程,直至它到达最终的处理程序之前要经过一系列的步骤和过程,这个步骤和过程称为ASP.NET处理管道。

管道模型使用一个HttpContext对象去描述声明request/response信息。这个对象在HttpApplication和handler之间来回传递。HttpContext对象通过属性来描述request和response信息。下图展示了部分HttpContext类常用的属性。            技术图片

二:Module的详解

1:HttpModule:可以看做是一个拦截器,给我们在特定的事件处理请求的机会。HttpModule有很多应用,例如,我们要在每个请求的页面事件前加载Session数据,那么就用到SessionModule等等;

2:asp.net4.0提供了路由机制也是建立在一个UrlRouteModule上面的,它在请求映射到具体程序前拦截,然后重新映射。MVC又是建立在路由机制的基础上的。

3:怎么查看系统默认自带的Module以及怎么配置自定义的module。

A:打开C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config中的web.config,然后找到system.web节点下面的HttpModules下Module,一般系统自带的webconfig不要轻易去修改,因为这个是针对于全局的。如果要修改只需要修改自己项目中的webconfig

技术图片

 B:打开项目所在的webconfig,注释见下图:

技术图片

4:怎么自定义module

右键 -》添加新项 --》选择Asp.net模块即自己定义的一个module已经创建完成。

技术图片

module的注册一般都是在Init方法里面来完成的,下面附上自己新定义的module代码:

技术图片
 1 public class CustomHttpModule : IHttpModule
 2     
 3         public void Dispose()
 4         
 5             Console.WriteLine();
 6         
 7 
 8         public event EventHandler CustomHttpModuleHandler;
 9 
10         /// <summary>
11         /// 注册动作
12         /// </summary>
13         /// <param name="context"></param>
14         public void Init(HttpApplication application)
15         
16             #region 为每一个事件,都注册了一个动作,向客户端输出信息
17             application.AcquireRequestState += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "AcquireRequestState        "));
18             application.AuthenticateRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "AuthenticateRequest        "));
19             application.AuthorizeRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "AuthorizeRequest           "));
20             application.BeginRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "BeginRequest               "));
21             application.Disposed += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "Disposed                   "));
22             application.EndRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "EndRequest                 "));
23             application.Error += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "Error                      "));
24             application.LogRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "LogRequest                 "));
25             application.MapRequestHandler += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "MapRequestHandler          "));
26             application.PostAcquireRequestState += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostAcquireRequestState    "));
27             application.PostAuthenticateRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostAuthenticateRequest    "));
28             application.PostAuthorizeRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostAuthorizeRequest       "));
29             application.PostLogRequest += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostLogRequest             "));
30             application.PostMapRequestHandler += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostMapRequestHandler      "));
31             application.PostReleaseRequestState += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostReleaseRequestState    "));
32             application.PostRequestHandlerExecute += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostRequestHandlerExecute  "));
33             application.PostResolveRequestCache += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostResolveRequestCache    "));
34             application.PostUpdateRequestCache += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PostUpdateRequestCache     "));
35             application.PreRequestHandlerExecute += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PreRequestHandlerExecute   "));
36             application.PreSendRequestContent += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PreSendRequestContent      "));
37             application.PreSendRequestHeaders += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "PreSendRequestHeaders      "));
38             application.ReleaseRequestState += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "ReleaseRequestState        "));
39             application.RequestCompleted += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "RequestCompleted           "));
40             application.ResolveRequestCache += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "ResolveRequestCache        "));
41             application.UpdateRequestCache += (s, e) => application.Response.Write(string.Format("<h1 style=‘color:#00f‘>来自MyCustomModule 的处理,0请求到达 1</h1><hr>", DateTime.Now.ToString(), "UpdateRequestCache         "));
42             #endregion
43         
44     
View Code

自己定义的module已经完成,这样创建完成后,module还不会生效,如果想要其生效,需要在webconfig中的<system.webServer>(因为是该节点是针对于IIS中的集成模式)节点中配置:

 <add name="CustomHttpModule" type="Ruanmou.MVC5.Utility.Pipeline.CustomHttpModule,Ruanmou.MVC5"/>

 这样既可生效。具体详细配置见上面的第3点

5:怎么看当前请求中运用到了哪些module以及事件呢,可以通过下面代码来查看:

技术图片
 1  public ActionResult Module()
 2  
 3      HttpApplication app = base.HttpContext.ApplicationInstance;
 4 
 5      #region 得到当前请求中所有的Event事件
 6      List<SysEvent> sysEventsList = new List<SysEvent>();
 7      int i = 1;
 8      foreach (EventInfo e in app.GetType().GetEvents())
 9      
10          sysEventsList.Add(new SysEvent()
11          
12              Id = i++,
13              Name = e.Name,
14              TypeName = e.GetType().Name
15          );
16      
17      #endregion
18 
19      #region 得到当前HttpApplication中所有的module,包括系统自带跟自己自定义的
20      List<string> list = new List<string>();
21      foreach (string item in app.Modules.Keys)
22      
23          list.Add($"item: app.Modules.Get(item)");
24      
25      #endregion
26 
27      ViewBag.Modules = string.Join(",", list);
28      return View(sysEventsList);
29  
View Code

 

三:管道中19个标准事件

1:HttpHandler:可以看做一个处理器,它负责处理请求,输出数据。aspx,ashx或者说实现了IHttpHandler的都是HttpHandler。

2:系统的web.config配置的默认的对应的处理器。是根据后缀名然后映射到不同的处理器上面

技术图片

 

随便找一个.aspx对应的handler,通过反编译会得到证实

技术图片

 

3:系统自带默认的事件

 技术图片

四:总结

  MVC URLRouting Module对进入server的request进行了拦截,然后对request的handlerjinxingltes的处理。asp.net WebForm和asp.net MVC两者的不同,是在于最终使用的IHttpHandle的不同。WebForm中使用的是Page这个Handler,MVC中使用的是MVCHander。 

以上是关于Asp.net管道模型之(HttpModules 和 HttpHandler)的主要内容,如果未能解决你的问题,请参考以下文章

httpModules与httpHandlers

检测到在集成的托管管道模式下不适用的 ASP.NET 设置。

如何修复 HTTP 错误 500.22 - 内部服务器错误检测到 ASP.NET 设置不适用于集成托管管道模式

检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为经典模式)。 - CatcherX

webconfig中注册HttpHandler报错:检测到在集成的托管管道模式下不适用的 ASP.NET 设置。

Owin管道与asp.net管道模型