httpModules与Http模块

httpModules是往当前应用程序添加HttpModule(http模块)的标签。配置节以下 程序员

<httpModules>
<add name="ModuleName"
type=".NET Class, Assembly [,Version=version number]
[,Culture=culture] [,PublicKeyToken=token]"/>
<remove... />
<clear/>
</httpModules>

   

提起httpModule不得不提一下Http请求处理流程 web

ASP.NET对请求处理的过程缓存

当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)以后,将这个请求转交给ASPNET_ISAPI.dll,ASPNET_ISAPI.dll会经过http管道(Http PipeLine)将请求发送给ASPNET_WP.exe进程,在ASPNET_WP.exe进程中经过HttpRuntime来处理这个请求,处理完毕将结果返回客户端。 安全

Http 管道服务器

1. HttpRuntimeHttp请求转交给 HttpApplicationHttpApplication表明着程序员建立的Web应用程序。HttpApplication建立针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其余对象,主要是HttpRequestHttpResponseHttpSessionState等。这些对象在程序中能够经过Page类或者Context类进行访问。、 app

2. 接下来Http请求经过一系列Module,这些ModuleHttp请求具备彻底的控制权。这些Module能够作一些执行某个实际工做前的事情。 学习

3. Http请求通过全部的Module以后,它会被HttpHandler处理。在这一步,执行实际的一些操做,一般也就是.aspx页面所完成的业务逻辑。可能你会以为在建立.aspx页面并无体会到这一过程,可是,你必定知道,.aspx 页面继承自Page类,咱们看一下Page类的签名: 网站

public class Page : TemplateControl, IHttpHandler{

    // 代码省略

}

 

能够看到,Page类实现了IHttpHandler接口,HttpHandler也是Http请求处理的最底层。 this

4.HttpHandler处理完之后,Http请求再一次回到Module,此时Module能够作一些某个工做已经完成了以后的事情。 spa

从第二步到第四步能够用下面的图来展现

 

在http请求的处理过程当中,只能调用一个HttpHandler,但能够调用多个HttpModule。

   

下面则详细说说HttpModule  

HTTP 模块是一个在每次针对应用程序发出请求时调用的程序集。HTTP 模块做为请求管道的一部分调用,它们可以在整个请求过程当中访问生命周期事件。所以,HTTP 模块使您能够检查传入的请求并根据该请求进行操做。它们还使您能够检查传出的响应并修改它。

ASP.NET HTTP 模块针对全部请求调用,这与 ISAPI 筛选器相似。可是它们是用托管代码编写的,并且能够与 ASP.NET 应用程序的生命周期彻底集成。能够将自定义模块源代码放在应用程序的 App_Code 文件夹中,也能够将通过编译的自定义模块做为程序集放在应用程序的 Bin 文件夹中。

ASP.NET 使用模块来实现各个应用程序功能,其中包括 Forms 身份验证、缓存、会话状态和客户端脚本服务。在每种状况下,若是这些服务处于启用状态,模块会做为请求的一部分调用,并执行在任何单一页请求范围以外的任务。模块可使用应用程序事件,可能会引起可在 Global.asax 文件中处理的事件。

功能

模块能够订阅多种请求管道通知。模块能够接收 HttpApplication 对象的事件通知。

使用场景

HTTP 模块一般具备如下用途:

  • 安全 由于您能够检查传入的请求,因此 HTTP 模块能够在调用请求页、XML Web services 或处理程序以前执行自定义的身份验证或其余安全检查。在以集成模式运行的 Internet 信息服务 (IIS) 7.0 中,能够将 Forms 身份验证扩展到应用程序中的全部内容类型。
  • 统计信息和日志记录 由于 HTTP 模块是在每次请求时调用的,因此,您能够将请求统计信息和日志信息收集到一个集中的模块中,而不是收集到各页中。
  • 自定义的页眉或页脚 由于您能够修改传出响应,因此能够在每个页面或 XML Web services 响应中插入内容,如自定义的标头信息。

ASP.NET中一些内置的HttpModule

名称

类型

功能

OutputCache

System.Web.Caching.OutputCacheModule

页面级输出缓存

Session

System.Web.SessionState.SessionStateModule

Session状态管理

WindowsAuthentication

System.Web.Security.WindowsAuthenticationModule

用集成Windows身份验证进行客户端验证

FormsAuthentication

System.Web.Security.FormsAuthenticationModule

用基于Cookie的窗体身份验证进行客户端身份验证

PassportAuthentication

System.Web.Security.PassportAuthenticationModule

MS护照进行客户身份验证

RoleManager

System.Web.Security.RoleManagerModule

管理当前用户角色

UrlAuthorization

System.Web.Security.UrlAuthorizationModule

判断用户是否被受权访问某一URL

FileAuthorization

System.Web.Security.FileAuthorizationModule

判断用户是否被受权访问某一资源

AnonymousIdentification

System.Web.Security.AnonymousIdentificationModule

管理Asp.Net应用程序中的匿名访问

Profile

System.Web.Profile.ProfileModule

管理用户档案文件的创立及相关事件

ErrorHandlerModule

System.Web.Mobile.ErrorHandlerModule

捕捉异常,格式化错误提示字符,传递给客户端程序

   

下面摘抄了MSDN上的一个例子,自定义一个HttpModule

HttpModule必须实现接口System.Web.IHttpModule

 

namespace FastDoge.Study
{
    public class MyModule : IHttpModule
    {
        public void Dispose()
        {
            
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
            context.EndRequest +=
                (new EventHandler(this.Application_EndRequest));
        }

        private void Application_BeginRequest(Object source,
        EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.Write("<h1><font color=red>" +
                "HelloWorldModule: Beginning of Request" +
                "</font></h1><hr>");
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.Write("<hr><h1><font color=red>" +
                "HelloWorldModule: End of Request</font></h1>");
        }

    }

在 IIS 6.0 和 IIS 7.0 经典模式下运行的Web.config添加如下配置

 

<configuration>
  <system.web>
    <httpModules>
      <add name="myModule" type="FastDoge.Study.MyModule"/>
     </httpModules>
  </system.web>
</configuration>

因为鄙人用的是IIS7集成模式,配置会不同

  <system.webServer>
    <modules>
      <add name="myModule" type="FastDoge.Study.MyModule"/>
    </modules>
  </system.webServer>

 

效果以下所示

固然网站不能是空网站,不然输出的只是一行

<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>

的字符串。在Init方法中传入的HttpApplication 对象能够绑定的事件能够参考ASP.NET 应用程序生命周期中提到的,事件一共20几个。

在网上找了一幅图,列出了事件触发的顺序

BeginRequest和PreRequestHandlerExecute之间的事件是在服务器执行HttpHandler处理以前触发。

    PostRequestHandlerExecute和PreSendRequestContent之间的事件是在服务器执行Handler处理以后触发。

但是鄙人纠结的一点在于没发现某个ASP.NET内置的HttpModule调用了Handler。对于ASP.NET WebForm来讲,每一个Page都是一个Handler。而对ASP.NET MVC来讲,在以前看蒋金楠总是的著做时看到的是触发一个UrlRoutingModule,它在OnPostResolveRequestCache事件中给HttpContext指定了一个MvcHandler。这样就会使得HttpHandler会被调用?或许须要看一下源码了。另外还有一个值得学习的地方就是这种模块的添加以及往Application注册事件的形式,使得HttpApplication具有的较好的灵活性。

在入行之初写过一篇博客,就用到HttpModule,当时有位园友评论说能够用Global.asax。结合当时的场景确实如此。可是二者对比起来确定有弊有利。

模块相对于 Global.asax 文件具备以下优势:模块能够进行封装,所以能够在建立一次后在许多不一样的应用程序中使用。

用 Global.asax 文件的好处在于能够处理其余已注册事件,如 Session_Start 和 Session_End。此外,Global.asax 文件还容许您实例化可在整个应用程序中使用的全局对象。

当您必须建立依赖应用程序事件的代码,而且符合如下条件时,都应该使用模块:

  • 但愿在其余应用程序中重用该模块。
  • 但愿避免将复杂代码放在 Global.asax 文件中。
  • 该模块应用于管道中的全部请求(仅限 IIS 7.0 集成模式)。

当您必须建立依赖应用程序事件的代码而且不须要跨应用程序重用代码时,应该将代码添加到 Global.asax 文件中。

相关文章
相关标签/搜索