• ASP.NET的运行原理与运行机制 如何:为 IIS 7.0 配置 <system.webServer> 节


     ASP.NET的运行原理

     

     

      当一个HTTP请求到服务器并被IIS接收到之后,IIS首先通过客户端请求的页面类型为其加载相应的.dll文件,然后在处理过程中将这条请求发送给能够处理这个请求的模块。在ASP.NET 3.5中,这个模块叫做HttpHandler(HTTP处理程序组件),之所以.aspx文件可以被服务器处理,就是因为在服务器端有默认的HttpHandler专门处理.aspx文件。IIS在将这条请求发送给能够处理这个请求的模块之前,还需要经过一些HttpModule的处理,这些都是系统默认的Modules(用于获取当前应用程序的模块集合),在这个HTTP请求传到HttpHandler之前要经过不同的HttpModule的处理。这样做的好处,一是为了一些必需的过程,二是为了安全性,三是为了提高效率,四是为了用户能够在更多的环节上进行控制,增强用户的控制能力。ASP.NET 3.5运行原理如图1.1所示。

    图1.1  ASP.NET 3.5运行原理

      说明:HttpModule模块是一个组件,可以注册为ASP.NET 3.5请求生命周期的一部分,当处理该组件时,该组件可以读取或更改请求或响应。HttpModule模块通常用于执行需要监视每个请求的特殊任务,如安全或站点统计信息。

     (PS:

      HttpModule 概述:

      暂时先不考虑我们自己实现Http Module的情况。在.Net中,Http Module 是实现了IHttpModule接口的程序集。IHttpModule 接口本身并没有什么好大写特写的,由它的名字可以出,它不过是一个普普通通的接口而已。实际上,我们关心的是实现了这些接口的类,如果我们也编写代码实现了这个接口,那么有什么用途。一般来说,我们可以将Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。而 Http Module 的作用是与应用程序事件 密切相关的。

      我们通过Http Module在Http请求管道(Pipeline)中注册期望对应用程序事件做出反应的方法,在相应的事件触发的时候(比如说BeginRequest事件,它在应用程序收到一个Http请求并即将对其进行处理时触发),便会调用Http Module注册了的方法,实际的工作在这些方法中执行。.Net 本身已经有很多的Http Module,其中包括 表单验证Module(FormsAuthenticationModule), Session 状态Module(SessionStateModule),输出缓存Module (OutputCacheModule)等。

    更多了解:http://www.cnblogs.com/jimmyzhang/archive/2007/11/25/971878.html

      )

      ASP.NET 3.5运行机制如图1.2所示。

      通常情况下,ASP.NET框架搭建在Windows Server(服务器版操作系统)+IIS(Web服务器,是Internet信息服务管理器的英文缩写)环境中,在安装.NET Framework时,安装程序将会在IIS中注册ASP.NET所需的ISAPI扩展(aspnet_isapi.dll),这就使得作为ASP.NET宿主的IIS在接收到客户端的HTTP请求后,将响应请求的控制权交给ASP.NET运行。

      ASP.NET运行时接收到请求后,会判断站点是否为第一次被访问,如果是第一次访问,则运行初始化工作(如加载Bin目录中的DLL动态链接库,读取Web.Config网站配置文件,初始化HttpApplication实例,编译和加载Global.asax文件等)。ASP.NET运行时还负责创建请求响应线程的HttpContext上下文实例和创建承载响应结果的HttpTextWriter实例。然后,ASP.NET运行时寻找合适的HttpHandler(通常就是具有的ASP.NET页面)处理HTTP请求,并等HttpHandler返回请求处理结果。最后,ASP.NET运行时在完成一些后续工作之后,如保存Session、异常处理,再通过IIS把响应结构返回给客户端。

    图1.2  ASP.NET 3.5运行机制

      注意:ASP.NET ISAPI工作的主要任务就是安排ASPNET_WP.exe处理请求,并监视ASPNET_ WP.exe进程的执行情况,如果ASPNET_WP.exe进程不能完成任务,ASP.NET ISAPI就安排一个新的ASPNET_WP.exe来处理工作。ASPNET_WP.exe的主要任务是将请求交给一系列称为HTTP管道的托管对象。如果把ASP.NET ISAPI比做销售商,那么ASPNET_WP.exe就是生产商,而HTTP管道就是生产的流水线,负责流水线的小组就是HttpRuntime。生产商ASPNET_WP.exe会将订单(HTTP请求)交给HttpRuntime小组的工作人员ProcessRequest(HttpWorkerRequest wr),HttpRuntime根据内部的分工,最终由ProcessRequestInternal(HttpWorkerRequest wr)在流水线上进行生产。

    向模块注册中添加 precondition 属性,并将其值设置为managedHandler。

    此条件会导致仅在请求 ASP.NET 应用程序资源(例如 .aspx 文件或托管处理程序)时才调用该模块。该资源中不包括静态文件(例如 .htm 文件)。

    其 configuration 节将类似于以下示例。

    复制代码
    <configuration>
      <system.webServer>
        <modules>
          <add name="CustomModule" type="Samples.CustomModule" 
               precondition="managedHandler" />
        </modules>
        <defaultDocument>
          <files>
            <add value="Products.aspx" />
          </files>
        </defaultDocument>
      </system.webServer>
    </configuration>
    复制代码
    Integrated mode — 集成模式
    IIS 7.0 中的一种配置,其中,IIS 和 ASP .NET 基于支持使用 .NET Framework 和本机组件创建的组件的管线共享请求处理。在集成模式中,ASP .NET 组件(如 HTTP 模块)可用于管理所有 Web 请求,其中包括那些对非 ASP .NET 资源的请求。
    复制代码
     <system.webServer>
        <!--集成模式-->
        <modules>
          <add name="BaseHttpHandler" type="Frame.Core.BaseHttpHandler" />
        </modules>
        <handlers>
     </system.webServer>
    复制代码

     zhongkeMVC原理:自定义handler(必须实现IhttpModel,想用请求管道的19个事件就必须实现,init是最主要得方法)并且在web.config注册

    通过web.config配置注册模块托管代码,截获每次请求到baseHandler,在此分析请求地址中的controller、action,然后反射调用相应的方法,通过VTempalte模板替换所有HTML中相应的值,最后返回给用户。

    ps:baseHandler 在global之前

    程序启动先根据web.config去创建baseHandler并且执行他的init方法,还有VT模板的一些初始化 方法,此时执行了三个方法

    this.OnInit(EventArgs.Empty);
    this.OnLoad(EventArgs.Empty);
    this.OnRender(EventArgs.Empty);

    然后才执行 global中的 Application_Start事件(Application_Start 和baseHandler中init只是程序启动时执行一次,每次请求的时候不再执行那两个方法)

     

    每次回话开始的的时候先执行global中Session_Start然后执行正常的每次请求

    每次请求 先执行Application_BeginRequest  然后是baseHandler中的那通过 IHttpHandler.ProcessRequest 调用那三个初始化方法

     public class BaseHttpHandler : TemplatePageBase, IHttpModule, IRequiresSessionState
    TemplatePageBase 是他的父类  所以先之心BaseHttpHandler 中的方法

    2016-7-25
    现在的理解 他这个框架没用注册任何时间 就是利用 第八个创建请求对象的的时候 就创建了httphandler 然后到11 12事件之间的时候执行里面的processrequest方法,根据分析地址去找控制器 去找html文件, 替换模板内容

     一般情况下  称HttpModel为过滤器  

    global中有些方法是和管道中的时间对应的  不过是先执行自定义模块中管道中绑定的方法,然后在执行global中的 一一对应

     processRequest调用管道19个事件  到第12个的时候  有一个hanler的processrequest的方法

    一般处理程序和aspx页到12个都执行这个方法

    一般处理程序:是程序员写的处理代码

    aspx:是页面的整个生命周期

    托管和非托管是什么意思?

    托管代码 (managed code) :由公共语言运行库环境(而不是直接由操作系统)执行的代码。托管代码应用程序可以获得公共语言运行库服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。 Unmanaged Code - 非托管代码 :在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务;它与托管代码不同,后者从公共语言运行库中获得这些服务。非托管代码的英文名是Unmanaged Code ,它是在公共语言运行库环境的外部,由操作系统直接执行的代码。

    MVC怎么进入管道的

    httpapplaction 创建之后会遍历创建所有module 包括 URLRoutingMdeule路由处理

    遍历完URLRoutingMdeule 执行他的init方法,完成了请求管道中第七个事件的注册
    通过反编译可以看到 URLRoutingMdeule 注册了第七个事件
    遍历完 执行 processRequest 开始进入管道 到第七个事件的时候
    执行注册的方法,根据路由数据创建MVChandler 实现了Ihttphanlder
    到十一、十二个事件之间 执行 processrequest(去找控制器 、方法)

    这个processrequest
    asp.net:page_load一系列方法
    MVC:去匹配控制器、方法
    一般处理程序:程序员直接实现代码

    一系列处理 到httpruntime 然后创建 httpcontext 并且对象池获取 Application

    然后进入管道piplines

    7/8事件之间  获取 httpHandler  

    MVC 生命周期

     https://www.cnblogs.com/fzrain/p/3651693.html

    HttpApplication的处理管道19个事件。

    https://www.cnblogs.com/wolf-sun/p/5236185.html

    HttpApplication对象是由Asp.net帮助我们创建的,它是asp.net中处理请求的重要对象。为了便于扩展,HttpApplication采用处理管道的方式进行处理,将处理的步骤分为多个步骤,每个步骤通过事件的形式暴露给程序员,这些事件按照固定的处理顺序依次触发,程序员通过编写事件处理方法就可以定义一个请求的扩展过程。

    对于HttpApplication,到ASP.NET 4.0,提供了19个标准事件。

    1.BeginRequest:asp.net开始处理请求的第一个事件,表示处理的开始。

    2.AuthenticateRequest:验证请求,一般用来取得请求的用户信息。

    3.PostAuthenticateRequest:已经获取请求的用户信息。

    4.AuthorizeRequest:授权,一般用来检查用户的请求是否获得权限。

    5.PostAuthorizeRequest:用户请求已经获得授权。

    6.ResolveRequestCache:获取以前处理缓存的处理结果,如果以前缓存过,那么,不用再进行请求的处理工作,直接返回缓存的结果。

    7.PostResolveRequestCache:已经完成缓存的处理工作。

    8.PostMapRequestHandler:已经根据用户的请求,创建了请求的处理器对象。

    9.AcquireRequestState:取得请求的状态,一般用于session

    10.PostAcquireRequestState:已经获得了session

    11.PreRequestHandlerExecute:准备执行处理程序。

    12.PostRequestHandlerExecute:已经执行了处理程序

    13.ReleaseRequestState:释放请求的状态。

    14.PostReleaseRequestState:已经释放了请求的状态。

    15.UpdateRequestCache:更新缓存。

    16.PostUpdateRequestCache:已经更新了缓存。

    17.LogRequest:请求的日志操作

    18.PostLogRequest:已经完成请求的日志操作。

    19.EndRequest:本次请求处理完成。

    ASP.NET MVC中的Global.asax文件

    1.global.asax文件概述 

    global.asax这个文件包含全局应用程序事件的事件处理程序。它响应应用程序级别和会话级别事件的代码。  
    运行时, Global.asax 将被编译成一个动态生成的 .NET Framework 类,该类是从HttpApplication基类派生的。
    因此在global.asax中的代码可以访问HttpApplication类中所有的public或者protected的成员
    global.asax不被用户直接请求,但global.asax中的代码会被自动执行来响应特定的应用程序事件。
    global.asax是可选的,而且在一个web项目中是唯一的,它应该处于网站的根目录。

    2.一个请求的完整处理过程

    以下过程由Internet Information Service(inetinfo.exe)(IIS)执行
    1.客户端发出请求
    2.验证请求
    3.给请求授权
    4.确定请求的缓存
    5.获取缓存状态
    6.在请求的处理程序执行前
    7.http处理程序执行请求 (asp.net页面由aspnet_wp.exe执行)
    8.在请求的处理程序执行后
    9.释放请求状态
    10.更新请求缓存
    11.请求结束

    3.global.asax中的事件

    global.asax中的所有事件可以分成两种,一种是满足特定事件时才会被触发,一种是每次请求都会被按照顺序执行的事件。

    复制代码
     public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //在Web应用程序的生命周期里就执行一次
                //在应用程序第一次启动和应用程序域创建事被调用
                //适合处理应用程序范围的初始化代码
            }
    
            void Application_End(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //在应用程序关闭时运行的代码,在最后一个HttpApplication销毁之后执行
                //比如IIS重启,文件更新,进程回收导致应用程序转换到另一个应用程序域
            }
    
            void Session_Start(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //会话开始时执行
            }
    
            void Session_End(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //会话结束或过期时执行
                //不管在代码中显式的清空Session或者Session超时自动过期,此方法都将被调用
            }
    
            void Application_Init(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //在每一个HttpApplication实例初始化的时候执行
            }
    
            void Application_Disposed(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //在应用程序被关闭一段时间之后,在.net垃圾回收器准备回收它占用的内存的时候被调用。
                //在每一个HttpApplication实例被销毁之前执行
            }
    
            void Application_Error(object sender, EventArgs e)
            {
                //不是每次请求都调用
                //所有没有处理的错误都会导致这个方法的执行
            }
    
    
            /*********************************************************************/
            //每次请求都会按照顺序执行以下事件
            /*********************************************************************/
    
            void Application_BeginRequest(object sender, EventArgs e)
            {
                //每次请求时第一个出发的事件,这个方法第一个执行
            }
    
            void Application_AuthenticateRequest(object sender, EventArgs e)
            {
                //在执行验证前发生,这是创建验证逻辑的起点
            }
    
            void Application_AuthorizeRequest(object sender, EventArgs e)
            {
                //当安全模块已经验证了当前用户的授权时执行
            }
    
            void Application_ResolveRequestCache(object sender, EventArgs e)
            {
                //当ASP.NET完成授权事件以使缓存模块从缓存中为请求提供服务时发生,从而跳过处理程序(页面或者是WebService)的执行。
                //这样做可以改善网站的性能,这个事件还可以用来判断正文是不是从Cache中得到的。
            }
    
            //------------------------------------------------------------------------
            //在这个时候,请求将被转交给合适程序。例如:web窗体将被编译并完成实例化
            //------------------------------------------------------------------------
    
            void Application_AcquireRequestState(object sender, EventArgs e)
            {
                //读取了Session所需的特定信息并且在把这些信息填充到Session之前执行
            }
    
            void Application_PreRequestHandlerExecute(object sender, EventArgs e)
            {
                //在合适的处理程序执行请求前调用
                //这个时候,Session就可以用了
            }
    
            //-------------------------------------------------
            //在这个时候,页面代码将会被执行,页面呈现为HTML
            //-------------------------------------------------
    
            void Application_PostRequestHandlerExecute(object sender, EventArgs e)
            {
                //当处理程序完成对请求的处理后被调用。
            }
    
            void Application_ReleaseRequestState(object sender, EventArgs e)
            {
                //释放请求状态
            }
    
            void Application_UpdateRequestCache(object sender, EventArgs e)
            {
                //为了后续的请求,更新响应缓存时被调用
            }
    
            void Application_EndRequest(object sender, EventArgs e)
            {
                //EndRequest是在响应Request时最后一个触发的事件
                //但在对象被释放或者从新建立以前,适合在这个时候清理代码
            }
    
            void Application_PreSendRequestHeaders(object sender, EventArgs e)
            {
                //向客户端发送Http标头之前被调用
            }
    
            void Application_PreSendRequestContent(object sender, EventArgs e)
            {
                //向客户端发送Http正文之前被调用
            }
        }
    复制代码

    原文: https://technet.microsoft.com/zh-cn/sysinternals/bb763179.aspx

              https://www.cnblogs.com/lgxlsm/p/5573088.html

  • 相关阅读:
    MySQL 8.0复制性能的提升(翻译)
    mongodb节点配置指南
    ProxySQL读写分离
    MySQL JOIN原理
    pt-summary
    Unity3D安卓打包参数配置与兼容性的关系分析
    unity3d 动画卡帧 动画合成 动画层次
    单机游戏计时器防作弊解决方案
    Unity3D占用内存太大的解决方法
    AndroidManifest.xml配置
  • 原文地址:https://www.cnblogs.com/xiaoshi657/p/4113779.html
Copyright © 2020-2023  润新知