zoukankan      html  css  js  c++  java
  • ASP.NET的底层体系2

    文章引导

                   1.ASP.NET的底层体系1

                   2.ASP.NET的底层体系2 

    引言

                 接着上一篇ASP.NET的底层体系1我们继续往下走

    一.System.Web.HttpRuntime.ProcessRequestInternal

                 我们看看ProcessRequestInternal的ProcessRequest

                              1.为请求创建一个新的HttpContext实例

                              2.获取一个HttpApplication实例

                              3.调用HttpApplication.Init()初始化管道事件

                              4.Init()触发HttpApplication.ResumeProcessing(),启动ASP.NET管道处理

                 一个新的HttpContext对象被创建,给它传递一个封装了ISAPI ECB的ISAPIWorkerRequest。HttpContext对象还包含一个非常有用的列表集合,你可以用它存储有关特定的请求需要的数据。上下文对象创建于一个请求生命周期的开始,在请求结束时被释放。因此保存在列表集合里的数据仅仅对当前的请求有效。

                      

     二.HttpApplication

                 每一个请求都将被路由到一个HttpApplication对象,HttpApplication类会为你的ASP.NET程序创建一个HttpApplication对象池,它负责加载程序和给每一个请求分发HttpApplication的引用,这个HttpApplication对象池的大小可以通过machine.config的ProcessModel节点中的MaxWorkerThreads选项配置。

                 HttpApplication对象池尽管以比较少的项目开始启动,但是同时有多个请求需要处理时,池中的对象也会随之增加。对于你的WEB程序而言,HttpApplication是一个外部容器,它对应到Global.asax文件定义的类。基于标准的web程序,它是你实际可以看到的HTTP运行时的第一个登录点。

                 HttpApplication主要用于HTTP管道的事件控制器,它的接口主要由事件构成。

                              BeginRequest

                              AuthenticateRequest

                              AuthorizeRequest

                              ResolveRequestCache

                              AcquireRequestState

                              PreRequireState

                              PostRequestHandlerExecute

                              ReleaseRequestState

                              UpdateRequestState

                              EndRequest

                每一个ASP.NET WEB程序运行在各自的AppDomain里,在AppDomain里同时运行着多个HttpApplication,这些实例存放在ASP.NET管理的一个HttpApplication对象池里。

                 观察AppDomain ID一致保持不变,而线程和HttpAapplication的ID在请求多的时候发生改变,这是因为HttpApplication是在一个集合里运行,下一个请求可能会再次使用同一个HttpApplication实例,所以有时候HttpApplication的ID会重复,一个HttpApplication实例对象并不依赖一个特定的线程,他们仅仅是被分配给处理当前请求的线程而已。

                 线程由.NET的ThreadPool提供服务,默认情况下,线程模型为多线程单元(MTA),你可以通过在ASP.NET的页面的@Page指令里设置属性ASCOMPAT="true"覆盖线程单元的状态。ASPCOMPAT意味着COM组件将在一个安全的环境下运行。实际上,这些HttpApplication对象运行在同一个AppDomain里是很重要的,这就是Asp.net如何保证web.config的改变或者单独的ASP.NET页面得到验证可以贯穿整个AppDomain。改变web.config的值导致AppDomain的重新开启。这确保了所有的HttpApplication实例可以看到这些改变,这是因为当AppDomain重新加载的时候,来自ASP.NET的那些改变将会在AppDomain启动的时候重新读取,当AppDomain重新启动的时候任何静态的引用都将重新加载。

                 这些改变将引起Web程序重新启动,对于已经存在于处理管道的请求,将继续通过原来的管道处理,而对于那些新的请求,将被路由到新的AppDomain里,为了处理这些“挂起的请求”,在这些请求超时结束之后,ASP.NET将强制关闭AppDomain甚至这些请求该没有处理。因此在一个特定的时间上,同一个HttpApplication实例在两个AppDomain里存在是有可能的。

                 HttpApplication负责请求的传输,通过触发事件,通知应用程序正在发生的事情。这个是作为HttpApplication.Init()方法的一部分实现的(System.Web.HttpApplication.InitInternal和HttpApplication.ResumeSteps())。在这个方法里,创建和启动了一系列事件,包括绑定事件处理器,Global.asax里的事件处理器会自动映射到对应的事件。

                 通过在web.config里注册,HttpModules和HttpHandlers可以被动态的加载,并且可以添加到事件链条上,HttpModules实际就是事件处理器,可以勾住指定的HttpApplication的事件,而HttpHandlers就是一个端点,可以被调用处理“应用程序级的请求处理”。

                 HttpApplication本身不知晓发送给WEB程序的数据,它只是个跑腿的,它是个事件的容器,负责事件之间的通信,传递HttpContext对象。

                     

                 ASP.NET管道一旦成功,HttpApplication将逐一触发事件,每一个事件将被触发,如果事件绑定了事件处理器,那么这些事件处理器将被调用,执行他们的任务。这个过程的目的是通过调用HttpHandler处理指定的请求,对于ASP.NET而言,HttpHandler是处理请求机制的核心。ASP.NET的页面和web Service都是HttpHandler的具体实现。HttpModule倾向于在分发给事件处理器之前和之后对内容进行处理

    三.HttpModule

                 模块的本质是过滤器,在功能上类似ASP.NET请求级别的ISAPI过滤,对于每一个穿过ASP.NET的HttpApplication对象的请求,模块都允许在HttpApplication对象触发的事件处理方法里截获这些请求,这些模块以类的形式存储在外部程序集里,可以在web.config里配置。当程序启动的时候加载,通过实现指定的接口和方法,模块就可以被添加在HttpApplication的事件链上,多个HttpModules可以勾住相同的事件,事件发生的顺序跟他们在web.confg里配置顺序。

                 <configuration>

                        <sysytem.Web>

                              <HttpModules>

                                     <add name="BasicAuthModule" type="HttpHandlers.BasicAuth,WebStore"/>

                 模块允许你查看每一个传入的web请求,基于触发的事件基础上执行操作。模块是非常有用的,它可以修改请求,输出响应的内容以及提供自定义的身份验证。另外可以在特定的程序里,针对ASP.NET的每一个请求提供响应前处理和响应后处理。 

                 HttpModule类似ISAPI的感觉,由于他们查看进入ASP.NET程序的每一个请求,但它们的局限性仅查看映射到某一个ASP.NET程序或虚拟目录的请求和映射到ASP.NET的请求,因此你可以查看所有的ASPX页面或者任意其他自定义的已经映射到这个程序的扩展名。

                 实现一个HttpModule模块,它包含两个方法:Init()和Dispose(),传递的事件参数中包含一个HttpApplication对象的引用,它会给你HttpContext的访问权限。

    public class BasicAuthCustomModule : IHttpModule
    {
    
       public void Init(HttpApplication application)
       {
          // *** Hook up any HttpApplication events
          application.AuthenticateRequest += 
              new EventHandler(this.OnAuthenticateRequest);
       }
       public void Dispose() { }
    
       public void OnAuthenticateRequest(object source, 
                                       EventArgs eventArgs)
       {
          HttpApplication app = (HttpApplication) source;
          HttpContext Context = HttpContext.Current;
          … do what you have to do…                     } 
    }

                 在Init()方法里,你可以勾住多个事件,因此在一个模块里,可以管理多个不同功能的操作。在HttpModules里使用HttpApplication的事件时,Response.End()和HttpApplication.CompleteRequest()方法会使ASP.NET跳过HttpApplication和模块的事件链。

    四.HttpHandler

                 HttpModule针对每一个传入ASP.NET程序的请求触发,HTTPHandler重于处理一个指定的请求映射。HttpHandler继承IHttpHandler,这个借口有一个方法ProcessReuqest()和一个属性IsReusable。ProcessRequest()可以获取一个HttpContext。

                 HttpHandler的关键操作是往Response对象里写输出数据,或者更确切的说,是往Response对象的OutputStream里写,这个就是真正返回到客户端的输出数据,在底层,由ISAPIWorkerRequest负责把OutputStream发回给ISAPI的ecb.WriteClient方法,因为ecb.WriteClient才是真正执行IIS产生输出数据的。

                 

  • 相关阅读:
    就业DAY7_web服务器_tcp三次握手四次挥手,返回浏览器需要的页面http服务器
    就业DAY7_web服务器_http协议
    就业DAY6_web服务器_正则表达式
    就业DAY5_多任务_协程
    就业DAY5_多任务_进程,进程池,队列
    win10安装ubuntu系统,报错WslRegisterDistribution failed with error: 0x8007019e
    解决ubuntu与win10双系统时间不同步
    Linux常用压缩解压命令
    ubuntu添加国内源
    解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 (转载)
  • 原文地址:https://www.cnblogs.com/xiaowangzi1987/p/9239282.html
Copyright © 2011-2022 走看看