zoukankan      html  css  js  c++  java
  • Asp.net MVC生命周期(转)

    Asp.net应用程序管道处理用户请求时特别强调"时机",对Asp.net生命周期的了解多少直接影响我们写页面和控件的效率。因此在2007年和2008年我在这个话题上各写了一篇文章:

    对于Asp.net MVC,我对它的生命周期还是兴趣很浓,于是提出两个问题:

    一个HTTP请求从IIS移交到Asp.net运行时,Asp.net MVC是在什么时机获得了控制权并对请求进行处理呢?处理过程又是怎样的?

    mvcapp 

     

    IIS7asp.net应用程序生命周期为例,下图是来自MSDN的一张HTTP请求处理过程发生事件的简图,后面我列出了一个完整的事件列表。既然Asp.net Mvc还是以Asp.net运行时为基础那么它必然要在Asp.net应用程序的生命周期中对请求进行截获。第一反应当然是去web.config里面去翻翻,我们可以看到UrlRoutingModule的配置节:

     

          <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

     

    下面要做的就顺理成章了,用Reflector打开这个程序集,可以看到以下代码:

     


     protected virtual void Init(HttpApplication application)
        {
            application.PostResolveRequestCache 
    += new EventHandler(this.OnApplicationPostResolveRequestCache);
            application.PostMapRequestHandler 
    += new EventHandler(this.OnApplicationPostMapRequestHandler);
        }

     

    看到这里我们的第一个问题实际上已经有了答案:时机是在PostResolveRequestCachePostMapRequestHandler.

     ResolveRequestCache event
    Occurs when ASP.NET finishes an authorization event to let the caching modules serve requests from the cache, bypassing execution of the event handler (for example, a page or an XML Web service).

    源文档 <http://msdn.microsoft.com/en-us/library/system.web.httpapplication.resolverequestcache.aspx>

     

     PostMapRequestHandler event
    Occurs when ASP.NET has mapped the current request to the appropriate event handler.

    源文档 <http://msdn.microsoft.com/en-us/library/system.web.httpapplication.postmaprequesthandler.aspx>

     

        我们使用VS2008Asp.net Mvc模板创建一个Demo完成后续的讨论,当我们访问/Home的时候发生了什么呢?

    1. Request 请求到来
    2. IIS 根据请求特征将处理权移交给 ASP.NET
    3. UrlRoutingModule将当前请求在 Route Table中进行匹配
    4. UrlRoutingModuleRouteCollection中查找Request匹配的RouteHandler,默认是MvcRouteHandler MvcRouteHandler 创建 MvcHandler实例.
    5.  MvcHandler执行 ProcessRequest.
    6.  MvcHandler 使用 IControllerFactory 获得实现了IController接口的实例,找到对应的HomeController
    7.  根据Request触发HomeControllerIndex方法
    8. Index将执行结果存放在ViewData
    9. HomeControllerIndex方法返回 ActionResult
    10. Views/Home/Index.aspx ViewData呈现在页面上
    11. Index.aspx执行ProcessRequest方法
    12. Index.aspx执行Render方法 输出到客户端

     

        通过阅读Asp.net Mvc的源码,我们可以得到更为详细的处理过程,我尽可能的忽略掉枝节,强调请求处理的流程.我们从Global.asax.cs文件切入,下面是一段样例代码,这里初始化了路由表,请特别特别注意注释部分:

     

    Code

     

    UrlRoutingMoudulePostResolveRequestCache阶段从RouteCollection中获取当前请求的RouteData.RouteData包含了一个请求处理对应的ControllerAction,RouteData这个作用贯穿请求的处理过程.RouteData中提取RouteHandler,这里默认是MvcRouteHandler,MvcRouteHandler获取HttpHandler,这里默认的是MvcHandler.

     

    PostResolveRequestCache

    rh 

      

    MvcHandler.ProcessRequest()中首先使用HttpContextWrapperHttpContext进行封装,封装的目的是为了解耦以获得可测试性.然后从RequestContext.RouteData中提取Controller名称.
    ControllerBuilder.GetControllerFactory --> ControllerFactory.CreateController --> IController.Execute

    ControllerBase实现了IController接口,Initialize时将RequestContext封装成为ControllerContext,Controller继承自ControllerBase并实现抽象方法ExecuteCore()

     

    mvchttp 

     

    ExecuteCore,Controller首先从RouteData中获得ActionName,然后执行ActionInvoker.InvokeAction.

    ActionInvoker中我们可以看到各种Filter,这是一种AOP实践:Action方法执行的前后执行若干方法.这里有四种Filter:ActionFilters,ResultFilters,AuthorizationFilters,ExceptionFilters.这四种Filter并不是封闭的,都有对应的接口,这四个只是默认实现.Filter的执行顺序是:AuthorizationFilter--->Action Filter.OnActionExecuting--->Action Method--->ActionFilter.OnActionExecuted.InvokeActionMethodWithFilters返回的结果是ActionExecutedContext,接下来将Controller执行OnResultExecuting 方法.ActionResult执行的结果可以是ViewResult,JsonResult,RedirectResult,ContentResult,或者是自定义的Result类型.

           如果返回的类型是ViewResult,我们先看一下ViewReuslt的继承关系:ViewResult-->ViewResultBase-->ActionResult,ViewResult包含两个属性ViewViewEngineCollection,实际上是包含了两个接口的实现:IViewEngine定义了怎么定位View/Partial View.IView定义了如何RenderView.默认的实现时WebFormViewWebFormViewEngine.

    Filter OnResultExecuted 最后一步了,可以这里捕获异常.上面我们说过还有ExceptionFilters,如果前面过程中的异常没有被捕获那么最终都会到冒泡到ExceptionFilters.

    • RouteData中获得ActionName
    • ActionInvoker.InvokeAction
    • 通过ControllerContext获取ControllerDescriptor
    • FindAction-获取ActionDescriptor
    • GetFilters
    • ModelBinderRequest中的数据转换成Action方法需要的参数
    • AuthorizationFilter
    • Action Filter.OnActionExecuting
    • Action
    • ActionFilter.OnActionExecuted
    • ResultFilter.OnResultExecuting
    • ActionResult Execution
    • ResultFilter.OnResultExecuted
    • WebFormViewEngine.CreateView
    • WebFormView.Render
    • ResultFilter.OnExecuted

    result 

     

    控制权归还到HttpApplication完成后续的生命周期.

    转:http://www.cnblogs.com/me-sa/archive/2009/06/01/MVCLifecycle.html

  • 相关阅读:
    (十三)学习CSS之两个class连一起隔空格和逗号
    (十二)学习CSS之box-sizing 属性
    (五)学习JavaScript之firstChild 属性
    (四)学习JavaScript之className属性
    (三)学习JavaScript之getElementsByTagName方法
    两张表一对多的连接,取多记录表中最新的一条数据
    oracle 快照
    Linux常用命令大全
    baidu 快递查询API
    oracle 触发器实现主键自增
  • 原文地址:https://www.cnblogs.com/luluping/p/1493372.html
Copyright © 2011-2022 走看看