• Pro ASP.NET MVC 5 Platform-第三章 ASP.NET 生命周期


    一、 ASP.NET 生命周期:

    ASP.NET MVC有两个生命周期:应用程序生命周期和请求生命周期。

    1. 应用程序生命周期 (Applicatin Life Cycle)

    从应用程序启动到应用程序结束的时间

    理解应用程序生命周期:

    What:应用程序生命周期通知允许在程序启动和关闭时,执行自己的代码

    Why:利用应用程序生命周期通知,我们可以在启动程序时完成一些配置工作,关闭程序时,释放一些资源。通常在应用程序启动时,配置依赖注入容器。

    How: 在MVC中,利用应用程序通知,我们配置路由,区域,全局过滤器,内容绑定等。

    在MVC中有关应用程序生命周期的文件:Global.asax.cs

    public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }

    HttpApplication: 定义 ASP.NET 应用程序中的所有应用程序对象共有的方法、属性和事件。此类是用户在 Global.asax 文件中所定义的应用程序的基类。

    利用应用程序生命周期,我们可以在程序启动和中止时,执行相应代码。

    Application_Start :应用程序启动后,我们可以配置写全局的设置

    Application_End: 应用程序结束前,我们可以释放一些资源,数据库链接

    需要注意一点:

    这两个方法没有在基类中定义,ASP.NET MVC方法通过反射找到这两个方法,要特别注意名称不要写错。

    测试程序启动和中止时的通知:System.Diagnostics.Debugger.Break method

    public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); System.Diagnostics.Debugger.Break(); } protected void Application_End() { System.Diagnostics.Debugger.Break(); } }

    2. 请求生命周期(Request Life Cycle)

    从mvc接受请求到发出响应的时间。

    理解请求生命周期

    What: 请求生命周期包括一系列事件的执行,也称为请求管道

    Why: 利用请求管道里的事件,我们可以自定义Module和Handler.

    How: MVC包含一些模块和处理 程序,模块拦截请求,选择Handler,handler负责具体选择Conroller和Action。

    请求管道中的事件:

    1、BeginRequest:HTTP管道开始处理请求时,会触发BeginRequest事件

    2、AuthenticateRequest:安全模块对请求进行身份验证时触发该事件

    3、PostAuthenticateRequest:安全模块对请求进行身份验证后触发该事件

    4、AuthorizeRequest:安全模块对请求进程授权时触发该事件

    5、PostAuthorizeRequest:安全模块对请求进程授权后触发该事件

    6、ResolveRequestCache:缓存模块利用缓存直接对请求进程响应时触发该事件

    7、PostResolveRequestCache:缓存模块利用缓存直接对请求进程响应后触发该事件

    8、PostMapRequestHandler:对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进程处理。对于每个请求,ASP.NET会根据扩展名选择匹配相应的HttpHandler类型,成功匹配后触发该事件

    9、AcquireRequestState:状态管理模块获取基于当前请求相应的状态(比如SessionState)时触发该事件

    10、PostAcquireRequestState:状态管理模块获取基于当前请求相应的状态(比如SessionState)后触发该事件

    11、PreRequestHandlerExecute:在实行HttpHandler前触发该事件

    12、PostRequestHandlerExecute:在实行HttpHandler后触发该事件

    13、ReleaseRequestState:状态管理模块释放基于当前请求相应的状态时触发该事件

    14、PostReleaseRequestState:状态管理模块释放基于当前请求相应的状态后触发该事件

    15、UpdateRequestCache:缓存模块将HttpHandler处理请求得到的相应保存到输出缓存时触发该事件

    16、PostUpdateRequestCache:缓存模块将HttpHandler处理请求得到的相应保存到输出缓存后触发该事件

    17、LogRequest:为当前请求进程日志记录时触发该事件

    18、PostLogReques:为当前请求进程日志记录后触发该事件

    19、EndRequest:整个请求处理完成后触发该事件

    注意:

    ASP.NET 会创建多个MvcApplication实例来处理请求,这些实例可以复用,但是每个实例一次只能处理一个请求。

    3. 理解Module和Handler

    HttpModule

    ASP.NET拥有一个高度可扩展的引擎,并且能够处理对于不同资源类型的请求。这就是HttpModule。当一个请求转入ASP.net管道时,最终负责处理请求的是与资源相匹配的HttpHandler对象,但是在HttpHandler进行处理之前,ASP.NET先会加载并初始化所有配置的HttpModule对象。

    HttpModule初始化的时候,会将一些回调事件注入到HttpApplication相应的事件中。所有的HttpModule都实现了IHttpModule接口,该接口有一个有一个Init方法。

    HttpHandler

    对于不同的资源类型的请求,ASP.NET会加载不同的HttpHandler来处理。所有的HttpHandler都实现了IhttpHandler接口。

    我们看到该接口有一个方法ProcessRequest,顾名思义这个方法就是主要用来处理请求的。所以说每一个请求最终分发到自己相应的HttpHandler来处理该请求。

    HttpHandle和HttpModule的区别:

    HttpHandler是每个请求的主要处理对象,而HttpModule可以选择请求交给哪个HttpHandler来处理, 甚至,它还可以选择它自己来处理请求。

    可以把Module想象成老板,既接活,有时还自己干活,Handler是员工,只负责干活。

    1)用方法记录请求生命周期中的事件:

    这种方法只能记录:PreRequestHanderExecute之后PostRequestHandlerExecute之前的事件

    protected void Application_BeginRequest() { RecordEvent("BeginRequest"); } private void RecordEvent(string name) { List<string> eventList = Application["events"] as List<string>; if (eventList == null) { Application["events"] = eventList = new List<string>(); } eventList.Add(name); }

    显示事件信息:

    return View(HttpContext.Application["events"]);

    2)利用HttpApplication类的事件,记录事件信息

    BeginRequest += (src, args) => RecordEvent("BeginRequest"); public MvcApplication() { BeginRequest += (src, args) => RecordEvent("BeginRequest"); AuthenticateRequest += (src, args) => RecordEvent("AuthentucateRequest"); PostAuthenticateRequest += (src, args) => RecordEvent("PostAuthenticateRequest"); } private void RecordEvent(string name) { List<string> eventList = Application["events"] as List<string>; if (eventList == null) { Application["events"] = eventList = new List<string>(); } eventList.Add(name); }

    3)使用一个方法记录多个事件

    SystemWeb.HttpContext类的两个属性:CurrentNotification, IsPostNotification

    public MvcApplication() { BeginRequest += RecordEvent; AuthenticateRequest += RecordEvent; PostAuthenticateRequest += RecordEvent; } private void RecordEvent(object src, EventArgs args) { List<string> eventList = Application["events"] as List<string>; if (eventList == null) { Application["events"] = eventList = new List<string>(); } string name = Context.CurrentNotification.ToString(); if (Context.IsPostNotification) { name = "Post" + name; } eventList.Add(name); }

    Context.CurrentNotification返回为一个RequestNotification枚举值,描述当前执行的事件。

    MVC中关于RequestNotification枚举值的定义:

    4. ASP.NET 上下文对象:

    HttpContext基于HttpApplication的处理管道,由于HttpContext对象贯穿整个处理过程,所以,可以从HttpApplication处理管道的前端将状态数据传递到管道的后端,完成状态的传递任务。

    HttpContext的生命周期从服务器接收的HTTP请求开始到反应发送回客户端结束。

    HttpContext成员:

    属性:

    Application 为当前 HTTP 请求获取 HttpApplicationState 对象。

    ApplicationInstance 返回与当前请求相关的HttpApplication对象

    Cache 获取当前应用程序域的 Cache 对象。

    Current 为当前 HTTP 请求获取或设置 HttpContext 对象。

    CurrentHandler 获取表示当前正在执行的处理程序的 IHttpHandler 对象。

    IsDebuggingEnabled 显示当前应用程序是否处于调试状态

    Items 获取可用于在 HTTP 请求过程中在 IHttpModule 接口和 IHttpHandler 接口之间组织和共享数据的键/值集合。

    GetSection(name) 获取当前应用程序的默认配置的指定配置节。

    Request 为当前 HTTP 请求获取 HttpRequest 对象。

    Response 为当前 HTTP 响应获取 HttpResponse 对象。

    Session 为当前 HTTP 请求获取 HttpSessionState 对象。

    Server 获取提供用于处理 Web 请求的方法的 HttpServerUtility 对象。

    Timestamp 获取当前 HttpContext创建时的时间点,类型为:DateTime

    Trace 用于记录诊断信息

    CurrentNotification 获取请求管道中当前执行的事件,返回RequestNotification枚举

    IsPostNotification 是否Post类事件

    方法:

    AddError 将异常添加到当前 HTTP 请求的异常集合中。

    ClearError 清除当前 HTTP 请求的所有错误

    GetGlobalResourceObject 获取应用程序级别的资源。

    GetLocalResourceObjec   获取页级别的资源。

    GetSection 获取当前应用程序的默认配置的指定配置节。

    RemapHandler 用于为请求指定处理程序。

    RewritePath 重写路径,以便后续的Asp.net以为这是才是真正的地址。RewritePath用在无 Cookie 会话状态中。

    在ASP.NET MVC不同的组件获取HttpContext:

    Controller: 使用Controller定义的HttpContext

    View: 使用WebViewPage定义的Context属性

    Global.asax: 使用HttpApplication类定义的Context

    Module: HttpContext.Current

    Handler: ProcessRequest方法参数HttpContext

    通用: HttpContext.Current

    理解HttpContext,HttpContextBase,HttpContextWrapper的区别和联系:

    HttpContext

    HttpContext是最原始的ASP.NET Context. MVC的目的之一是能够单元测试。HttpContext没有base class,并且不是virtual,所以不能用单元测试,因为没有办法mock.

    HttpContextBase

    HttpContextBase, 是用来在MVC中替代HttpContext.但是这是一个abstract类,是mockable的。

    HttpContextWrapper

    HttpContextWrapper 是HttpContextBase的实现类,用来真正的替换HttpContext,可以用new HttpContextWrapper(HttpContext.Current)的方式来创建一个ttpContextWrapper.观察代码可以发 现,HttpContext与HttpContextWrapper在属性方法设置上基本上是一样的,只是HttpContextWrapper不是 virtual,有base class,因此可以进行单元测试。现在,关于使用到HttpContext的方法,可以通过HttpContextWrapper来进行单元测试。观察 ASP.NET MVC的源码可以发现,在最终MVCHandler(ASP.NET MVC的HttpHandler)中,调用ProcessRequest(HttpContext context)方法的时候,其内部把HttpContext转为HttpContextWrapper,然后调用了 ProcessRequest(HttpContext context)来进行后续的处理。

    5. HttpApplication

    HttpApplication:常用成员:

    Application 与HttpContext.Application属性对应,获取应用程序级别的状态数据

    CompleteRequest() 中止当前请求生命周期,直接跳转到LogRequest事件

    Context 获取当前请求的HttpContext对象

    Init() 当每个注册模块的Inti()方法执行时,执行Init()方法

    Modules 返回HttpModuleCollection对象,包括应用程序的所有模块细节

    RegisterModule(type) 注册新模块的静态方法

    Request 返回HttpContext.Request,如果为空,则引发HttpException异常

    Response 返回HttpContext.Response,如果为空,则引发HttpException异常

    Server 与HttpContext.Server属性相同

    Session 返回HttpContext.Session,如果为空,则引发HttpException异常

    处理属性异常(HttpApplication的使用):

    如果在应用程序级别的通知事件中,访问与请求上下文相关的属性,就会引发异常:HttpExecption.

    private void CreateTimeStamp() { string stamp = Context.Timestamp.ToLongTimeString(); if (Session != null) { //Session是请求上下文对象,在Global.asax类会引发异常 Session["request_timestamp"] = stamp; } else { Application["app_timestamp"] = stamp; } } 应该改为: private void CreateTimeStamp() { string stamp = Context.Timestamp.ToLongTimeString(); if (Context.Session != null) { Session["request_timestamp"] = stamp; } else { Application["app_timestamp"] = stamp; } }

    注意,在一次请求中,方法执行了两次,这是因为ASP.NET生命周期中全局Application类处理所有请求,不只是MVC框架的。

    6. HttpRequest

    描述当前正在处理的请求,提供当前请求的信息。

    HttpRequest类成员

    AcceptTypes 获取客户端支持的 MIME 接受类型的字符串数组。

    Browser 获取或设置有关正在请求的客户端的浏览器功能的信息。

    ContentEncoding 获取或设置实体主体的字符集

    ContentLength 客户端发送的内容长度(以字节计)。

    ContentType 获取或设置传入请求的 MIME 内容类型。

    CurrentExecutionFilePathExtension 获取当前请求的虚拟路径。

    Headers 获取 HTTP 头集合。

    HttpMethod 获取客户端使用的 HTTP 数据传输方法(如 GET、POST 或 HEAD)

    InputStream 获取传入的HTTP 实体主体的内容

    IsLocal 获取一个值,该值指示该请求是否来自本地计算机。

    MapPath(path) 将指定的虚拟路径映射到物理路径。

    RawUrl 获取当前请求的原始 URL

    RequestContext 返回RequestContext对象,提供了当前请求的路由信息

    Url 获取当前请求的原始 URL

    UrlReferrer 获取有关客户端上次请求的 URL 的信息,该请求链接到当前的 URL

    UserAgent 获取客户端浏览器的原始用户代理信息

    UserHostAddress 获取远程客户端的 IP 主机地址

    UserHostName 获取远程客户端的 DNS 名称

    UserLanguages 取客户端语言首选项的排序字符串数组

    Files 获取采用多部分 MIME 格式的由客户端上载的文件的集合。

    Form 获取表单变量集合

    Params 获取QueryString、Form、ServerVariables 和 Cookies 项的组合集合

    QueryString 获取 HTTP 查询字符串变量集合

    Item Item 从 Cookies、Form、QueryString 或 ServerVariables 集合中获取指定的对象

    ApplicationPath 获取服务器上 ASP.NET 应用程序的虚拟应用程序根路径

    Filter 获取或设置在读取当前输入流时要使用的筛选器

    在MVC的View中使用Request对象:

    <div class="panel panel-primary"> <h5 class="panel-heading">Request Properties</h5> <table class="table table-condensed table-striped"> <tr><th>Property</th><th>Value</th></tr> <tr><td>HttpMethod</td><td>@Request.HttpMethod</td></tr> <tr><td>IsLocal</td><td>@Request.IsLocal</td></tr> <tr><td>RawURL</td><td>@Request.RawUrl</td></tr> </table> </div>

    在ASP.NET MVC的不同组件中获取HttpRequest对象

    Controller Request

    View Request

    Global.asax Request

    Module context.Request,context为Init方法传入的参数类型为HttpApplication

    Handler context.Request,context为ProcessRequest方法的参数,类型为HttpContext

    通用: HttpContext.Current.Request

    7. HttpResponse

    HttpResponse标识当前请求的响应,提供方法和属性,利用它们,可以自定义响应内容。

    HttpResponse类成员:

    AppendHeader(name,val) 将 HTTP 头添加到输出流

    BufferOutput 获取或设置值,该值标识请求是否被缓冲输出

    Cache 获取网页的缓存策略(过期时间、保密性、变化子句)

    CacheControl 获取或设置输出的cache-control头部信息

    ContentType 获取或设置输出流的 HTTP MIME 类型。默认值为“text/html”

    Cookies 获取响应 Cookie 集合

    Filter 获取或设置一个包装筛选器对象,该对象用于在传输之前修改 HTTP 实体主体

    Charset 获取或设置HTTP的输出字符串编码

    Clear() 将缓冲区中的内容清除

    ClearContent() 与Clear方法相同

    ClearHeader() 移除响应流中的头部信息

    ContentEncoding 获取或设置响应内容的编码

    Headers 获取Response的头部信息集合

    IsClientConnected 客户端是否与服务端连接

    Output 返回TextWriter,用于将文本信息输出到Response

    OutputStream 启用到输出 Http 内容主体的二进制输出

    Redirect 将客户端重定向到新的 URL。指定新的 URL 并指定当前页的执行是否应终止。

    Status

    StatusCode 获取或设置返回给客户端的输出的 HTTP 状态代码。默认值为 200 (OK)。

    SuppressContent 设置是否将HTTP内容发送到客户端浏览器,若为true,网页将不会传送给客户端

    Write(data) 将数据写入HTTP响应流

    WriteFile(path) 将指定的文件直接写入HTTP内容输出流

    End 将当前所有缓冲的输出发送到客户端,停止该页的执行,并引发EndRequest事件。

    TransmitFile 将指定的文件直接写入 HTTP 响应输出流,而不在内存中缓冲该文件

    ASP.NET MVC不同的组件获取HttpResponse的方法:

    Controller Response

    View Response

    Global.asax Response

    Module context.Response,context为Init方法传入的HttpApplication类参数

    Handler context.Response,ProcessRequest方法的参数,类型为HttpContext

    通用: HttpContext.Current.Response

    参考:

    IIS5 IIS6

    https://docs.microsoft.com/zh-cn/previous-versions/aspnet/ms178473%28v%3dvs.100%29

    IIS7

    https://docs.microsoft.com/en-us/previous-versions/aspnet/bb470252(v=vs.100)

    ASP.NET 应用程序生命周期和请求周期

    https://www.cnblogs.com/alunchen/p/6252846.html

    WCF技术剖析之二:再谈IIS与ASP.NET管道

    http://www.cnblogs.com/artech/archive/2009/06/20/1507165.html

    Asp.net的生命周期应用之IHttpModule和IHttpHandler

    https://www.cnblogs.com/anlen/p/3613186.html

    ASP.NET-自定义HttpModule与HttpHandler

    https://www.cnblogs.com/fengzheng/p/3666774.html

    ASP.NET MVC请求处理管道生命周期的19个关键环节(13-19)

    http://www.cnblogs.com/darrenji/p/3795690.html

    ASP.NET 应用程序生命周期概述[转自MSDN]

    https://www.cnblogs.com/stg609/articles/1224943.html

    asp.net MVC 应用程序的生命周期

    http://www.cnblogs.com/yplong/p/5582576.html

    Asp.net的生命周期之应用程序生命周期

    https://www.cnblogs.com/anlen/p/3612048.html

    ASP.NET是如何在IIS下工作的

    https://www.cnblogs.com/fengzheng/p/3668283.html

    我心目中的Asp.net核心对象

    https://www.cnblogs.com/fish-li/archive/2011/08/21/2148640.html

    ASP.NET MVC5请求管道和生命周期

    https://www.jianshu.com/p/848fda7f79e0

    ASP.NET MVC中HttpContext, HttpContextBase, HttpContextWrapper联系

    https://www.cnblogs.com/BluceLee/p/3679052.html

    HttpContext请求上下文对象

    https://www.cnblogs.com/kissdodog/p/3360584.html

    IIS 7.0的集成模式和经典模式

    http://www.cnblogs.com/elock/archive/2009/12/26/1632838.html

    HttpRequest成员

    http://www.php230.com/1415360402.html

  • 相关阅读:
    踩坑:windows系统下,nodejs版本管理器无法使用n来管理
    华为,小米部分机型微信浏览器rem不适配的解决方案
    百度地图滚轮缩放时产生位置偏移 问题
    baidu-aip-SDK node.js 身份证识别
    iconfont 怎么在项目中使用图标库
    前端实用功能:选项卡切换
    input复选框操作的部分高频率使用代码
    HTML标签的命名/CSS标准化命名大全
    如何在网页中设置一个定时器计算时间?
    H5JS二维动画制作!two.js的基本操作class2
  • 原文地址:https://www.cnblogs.com/AlexanderZhao/p/12878929.html
Copyright © 2020-2023  润新知