• asp.net 处理流程


    原文:http://www.cnblogs.com/wupeiqi/archive/2013/03/03/2941295.html

    工作进程:

    在iis中,工作进程(w3wp.exe)运行着asp.net应用程序,管理并响应所有的请求,asp.net所有的功能都运行在工作进程下,当请求到来时,工作进程会生成request和response相关信息。

    应用程序池:

    应用程序池是工作进程的容器。通常用来隔开不同配置的工作进程,当一个程序出错或进程资源回收的时,其他池中的程序不受影响。

    注:当一个应用程序池包含多个工作进程时,叫做web garden

    如果我们看看iis 6 的结构,就会发现可以把他分为两部分

       内核模块(kernel model)

       用户模块(user model)

    内核模式是从iis 6.0被引入的,他包含一个叫做http.sys的文件,每当请求到来时,会首先触发该文件的响应。

    http.sys负责将请求传入到相应的应用程序池,但是http.sys是如何知道应该传到那个应用程序池?当然不是随机的,每当创建一个应用程序池,该池的ID就会生成并在http.sys文件中注册,因此该文件就能确定将请求发往那个程序池。

    以上便是IIS处理请求的第一步。接着,我们来看一下请求如何从HTTP.SYS传入应用程序池。

    在iis用户模块(user model),通过WAS(web admin services)从http.sys接收请求,并传入应用程序池。

    当应用程序池接收到请求之后,会传给工作进程(w3wp.exe),该进程检查请求的URL后缀,以确定加载那个ISAPI 扩展,然后将该请求传递给合适的 ISAPI 扩展。

    ASP.NET 处理已映射到它上的文件扩展名,如 .aspx、.ascx、.ashx 和 .asmx。

    即:当文件为上述后缀时,就要加载ASP.NET的ISAPI扩展(aspnet_isapi.dll)

    一旦工作进程加载了aspnet_isapi.dll,就会构造一个HttpRuntime类(密封类,防止派生),该类是应用程序的入口,通过该类中的ProcessRequest()方法创建HttpContext类,进入ProcessRequest方法之后,内部触发一系列的方法,最终创建一个HttpContext实例(可通过HttpContext.Current获取到这个实例),且该实例会在整个生命周期内存活。 

    之后HttpRuntime类会向HttpApplicationFactory类 提出请求,要求返回一个HttpApplication对象,HttpApplicationFactory在收到请求之后会检查是否有已经存在并且空闲的对象,如果有就取出一个HttpApplication对象返回给HttpRuntime类,如果没有,则要创建一个给HttpRuntime。

    HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context) 该方法创建HttpApplication实例并进行初始化,调用System.Web.HttpApplication.InitInternal()方法。

    当每次请求到来时要穿过httpModule到达httphandler,以便被响应。而httpmodule就被配置在httpApplication中。

    创建HttpApplication实例之后就是调用实例的InitInternal方法。

    InitInternal方法的主要功能如下:

      1、HttpAplication对象被初始化时,首先调用InitModule方法来加载Web.config文件中配置的所有HttpModule模块。

    例如:

    //Web.Config文件中
    <System.web>
        <httpModules>
                <add name="MyModuleName"  type="MyModule">
        </httpModules>
    </System.web>
    
    //自定义一个类(类型)
    
    public class MyModule:IHttpModule
    {
        public MyModule()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
    
        #region IHttpModule 成员
    
        public void Dispose()
        {
           
        }
    
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Mycontext_BeginRequest);
        }
    
        private void Mycontext_BeginRequest(object sender, EventArgs e)
        {
             //具体操作
             HttpContext.Current.Response.Write("BeginRequest11111111111111</br>"+dt);
        }
        #endregion
    }

    2、接着HookEventHandlesForApplicationAndModules方法被调用,这个方法完成Global.asax文件中配置的HttpModule或HttpApplication的绑定

    例如:

    //Global.asax文件
     void MyModule_ExposedEvent(object sender, EventArgs e)
     {
          Response.Write("xixi");
     }
    //MyModule.cs文件
    public class MyModule:IHttpModule
     {
         public event EventHandler ExposedEvent;//HttpModule事件,供Global.asax来订阅
     
         public void Init(HttpApplication context)
         {
             context.BeginRequest += new EventHandler(context_BeginRequest);//订阅HttpApplication的事件
         }
     
         void context_BeginRequest(object sender, EventArgs e)
         {
             HttpContext.Current.Response.Write("BeginRequest");
             OnExposedEvent(new EventArgs());//触发HttpModule自定义事件
         }
     
         protected void OnExposedEvent(EventArgs e)
         {
             if (ExposedEvent != null)
             {
                 ExposedEvent(this, e);
             }
         }
     
         public void Dispose()
         {
         }
     }
    上面的MyModule_ExposedEvent方法就会自动订阅了MyModule中的ExposedEvent事件。

    3、最后ApplicationStepManage对象的BuildSteps方法被调用,完成HttpApplication事件的绑定。

    4、按照顺序执行HttpApplication的各个事件。即:之前注册的对请求加以处理或者检查的HttpModule模块内容也得以执行。

    在这些事件中,第10个事件【根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理】,这个事件也是HttpHandler创建的地方。

     

    -----------------------------------------------------------------

    前面我们一直在说ASP.NET管线,那么,谁在控制管线过程?
    答案是:HttpApplication对象。
    1. HttpApplication细分它的处理过程,在不同阶段引发不同的事件,使得HttpModule通过订阅事件的方式加入到请求的处理过程中。
    2. 在请求的处理过程中,HttpApplication对象主要扮演着控制处理流程的推进作用。
    3. HttpApplication会在固定的阶段获取一个IHttpHandler实例,然后将请求的响应过程交给具体的IHttpHandler来实现。

    HttpApplication如何产生,如何工作?
    1. HttpApplication对象会被重用,当HttpRuntime不能从HttpApplicationFactory获取空闲的实例时,才会创建。
    2. HttpRuntime会将每个请求交给一个HttpApplication对象来处理。
    3. HttpApplication对象在初始化时负责加载全部的HttpModule。
    4. 每个HttpApplication对象会控制属于它的管线过程。

    HttpApplication是个非常重要的类型,它的许多功能都属于框架的基础部分,不需要我们调用, 因此,我们平时不会用到它。

     

    -------------------------------------------------------------------------

    HttpHandler根据用户请求的文件的扩展名(.aspx、.ascx、.ashx 、 .asmx)处理请求。

    HttpApplication在将某个请求交给HttpHandler实例来处理时,是通过接口来调用某个合适HttpHandler类中ProcessRequest方法,来处理请求。

    例如:自己定义个处理请求的HttpHandler。 (其实HttpHandler是只实现了IHttpHandler接口的类总称)

    //Web.Config文件中
    <httpHandlers>
          <add path="*.aspx" verb="*" type="SearchInfo.Handle"/>
          <add path="*.ascx" verb="*" type="SearchInfo.Handle2"/>
    </httpHandlers>
    //SearchInfo是命名空间,Handle是自己定义处理请求的类。
    //即:当一个请求Url后缀是 .aspx 时,就会交给自定的Handle类去处理
    
    namespace SearchInfo
    {
        /// <summary>
        /// Handle 的摘要说明
        /// </summary>
        public class Handle:IHttpHandler
        {
            public Handle()
            {
                //
                // TODO: 在此处添加构造函数逻辑
                //
            }
    
            #region IHttpHandler 成员
    
            public bool IsReusable
            {
                get { throw new Exception("The method or operation is not implemented."); }
            }
    
            public void ProcessRequest(HttpContext context)
            {
                HttpContext.Current.Response.Write("自定义Handler处理请求aspx");
            }
    
            #endregion
        }
    }

    所以,我们应该这样理解HttpHanlder:一个HttpHanlder用于响应一类特定的请求。

    在请求的处理过程中,HttpApplication对象主要扮演着控制管线处理流程的作用,它负责推进整个处理流程, 除了在不同阶段引发不同的事件外(供HttpModule使用),HttpApplication对象还会根据当前请求寻找一个合适的IHttpApplicationFactory实例, 并最终得到一个IHttpHandler的实例用于处理请求。

    应用程序环境图形

    当每次请求到来时要穿过httpModule到达httphandler,以便被响应。而httpmodule就被配置在httpApplication中。

    即流程为:

    每当请求Web服务器上的某些信息时,该请求首先会到达Http.SYS,然后Http.SYS将其发送到相应的应用程序池,应用程序池传给工作进程并加载ISAPI扩展,然后HttpRuntime对象会被创建,并通过HttpModule和HttpHandler处理请求。

    对于详细的HttpHandler和HttpModule可以在 Fish Li 的博客中:

  • 相关阅读:
    不一样的抽象工厂模式(设计模式七)
    不一样的工厂模式(设计模式六)
    asp .net core 静态文件资源
    asp .net core 中间件
    平时写文档的文档要求
    mysql 悲观锁和乐观锁(二)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Java实现 LeetCode 834 树中距离之和(DFS+分析)
    nmon数据采集参数
    Linux安装iostat命令
  • 原文地址:https://www.cnblogs.com/weekend001/p/3660605.html
Copyright © 2020-2023  润新知