您现在的位置是:网站首页> 编程资料编程资料

基于asp.net MVC 应用程序的生命周期(详解)_实用技巧_

2023-05-24 307人已围观

简介 基于asp.net MVC 应用程序的生命周期(详解)_实用技巧_

首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束。那么MVC应用程序从发出请求到获得响应,都做了些什么呢?

本文我们会详细讨论MVC应用程序一个请求的生命周期,从一个控件到另一个控件是怎样被处理的。我们还会详细介绍一下整个请求的生命周期中,用到的相关组件。因为在平常的开发过程中,我们可能知道怎样去使用MVC框架来处理相关的请求,大部分的时候我们只是在controller和action方法之间做相关的处理,对于真正内在的运行机制可能不是很了解。其实当我们对内在机制有了一定的了解以后,会发现微软的MVC框架的扩展性很强,到处都留有扩展接口,让我们通过扩展能够自己定义自己所需要的处理机制,这也正是为什么MVC框架如此出名的原因。

当我最开始学习使用mvc的时候,困扰我的一个问题就是,一个请求的流程控制是怎样的呢?从view到controller再到action之间经历了什么?那个时候我还不清楚HTTP module和HTTP handler在处理一个请求中扮演什么样的角色,起什么样的作用呢。毕竟MVC是一个web开发框架,在整个请求处理过程中,肯定包含了http module和http handler。其实还有很多相关的组件包含在一个完整的mvc应用程序请求生命周期里,在整个请求过程中他们都扮演者非常重要的角色。尽管大部分时候我们都使用的是框架提供的默认的函数,但是如果我们了解了每个控件所扮演的角色,我们就可以轻松的扩展和使用我们自己实现的方法,就目前来说MVC是扩展性比较强的框架。

下面是本章节的主要内容:

HttpApplication

HttpModule

HttpHandler

ASP.NET MVC运行机制

UrlRoutingModule

RouteHandler

MvcHandler

ControllerFactory

Controller

ActionInvoker

ActionResult

ViewEngine

HttpApplication

我们都知道,在ASP.NET MVC框架出现之前,我们大部分开发所使用的框架都是ASP.NET WebForm.其实不管是MVC还是WebForm,在请求处理机制上,大部分是相同的。这涉及到IIS对请求的处理,涉及的知识较多,我们就不做介绍了,下次有机会我写一篇专文。我们从HttpApplication说起。先看看微软官方是怎么定义HttpApplication的:

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

可能我翻译不是很准确,原文连接在这里:https://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.110).aspx

微软官方文档中Remark里有这么一段话:HttpApplication 类的实例是在 ASP.NET 基础结构中创建的,而不是由用户直接创建的。使用 HttpApplication 类的一个实例来处理其生存期中收到的众多请求。但是,它每次只能处理一个请求。这样,成员变量才可用于存储针对每个请求的数据。

意思就是说ASP.NET应用程序,不管是MVC还是WebForm,最终都会到达一个HttpApplication类的实例。HttpApplication是整个ASP.NET基础架构的核心,负责处理分发给他的请求。HttpApplication处理请求的周期是一个复杂的过程,在整个过程中,不同阶段会触发相映的事件。我们可以注册相应的事件,将处理逻辑注入到HttpApplication处理请求的某个阶段。在HttpApplication这个类中定义了19个事件来处理到达HttpApplication实例的请求。就是说不管MVC还是WebForm,最终都要经过这19个事件的处理,那么除了刚才说的MVC和WebFrom在请求处理机制上大部分都是相同的,不同之处在哪呢?他们是从哪里开始分道扬镳的呢?我们猜想肯定就在这19个方法中。我们继续往下看。

我们来看看这19个事件:

应用程序按照以下顺序执行由 global.asax 文件中定义的模块或用户代码处理的事件:

事件名称:

简单描述:

BeginRequest

ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生

AuthenticateRequest

当安全模块已建立用户标识时发生。注:AuthenticateRequest 事件发出信号表示配置的身份验证机制已对当前请求进行了身份验证。预订 AuthenticateRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证

PostAuthenticateRequest

当安全模块已建立用户标识时发生。PostAuthenticateRequest 事件在 AuthenticateRequest 事件发生之后引发。预订 PostAuthenticateRequest 事件的功能可以访问由 PostAuthenticateRequest 处理的任何数据

AuthorizeRequest

当安全模块已验证用户授权时发生。AuthorizeRequest 事件发出信号表示 ASP.NET 已对当前请求进行了授权。预订 AuthorizeRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证和授权

PostAuthorizeRequest

在当前请求的用户已获授权时发生。PostAuthorizeRequest 事件发出信号表示 ASP.NET 已对当前请求进行了授权。预订PostAuthorizeRequest 事件可确保在处理附加的模块或处理程序之前对请求进行身份验证和授权

ResolveRequestCache

ASP.NET 完成授权事件以使缓存模块从缓存中为请求提供服务时发生,从而跳过事件处理程序(例如某个页或 XML Web services)的执行

PostResolveRequestCache

ASP.NET 跳过当前事件处理程序的执行并允许缓存模块满足来自缓存的请求时发生。)在 PostResolveRequestCache 事件之后、PostMapRequestHandler 事件之前创建一个事件处理程序(对应于请求 URL 的页

PostMapRequestHandler

ASP.NET 已将当前请求映射到相应的事件处理程序时发生。

AcquireRequestState

ASP.NET 获取与当前请求关联的当前状态(如会话状态)时发生。

PostAcquireRequestState

在已获得与当前请求关联的请求状态(例如会话状态)时发生。

PreRequestHandlerExecute

恰好在 ASP.NET 开始执行事件处理程序(例如,某页或某个 XML Web services)前发生。

PostRequestHandlerExecute

ASP.NET 事件处理程序(例如,某页或某个 XML Web service)执行完毕时发生。

ReleaseRequestState

ASP.NET 执行完所有请求事件处理程序后发生。该事件将使状态模块保存当前状态数据。

PostReleaseRequestState

ASP.NET 已完成所有请求事件处理程序的执行并且请求状态数据已存储时发生。

UpdateRequestCache

ASP.NET 执行完事件处理程序以使缓存模块存储将用于从缓存为后续请求提供服务的响应时发生。

PostUpdateRequestCache

ASP.NET 完成缓存模块的更新并存储了用于从缓存中为后续请求提供服务的响应后,发生此事件。

LogRequest

ASP.NET 完成缓存模块的更新并存储了用于从缓存中为后续请求提供服务的响应后,发生此事件。

仅在 IIS 7.0 处于集成模式并且 .NET Framework 至少为 3.0 版本的情况下才支持此事件

PostLogRequest

ASP.NET 处理完 LogRequest 事件的所有事件处理程序后发生。

仅在 IIS 7.0 处于集成模式并且 .NET Framework 至少为 3.0 版本的情况下才支持此事件。

EndRequest

ASP.NET 响应请求时作为 HTTP 执行管线链中的最后一个事件发生。

在调用 CompleteRequest 方法时始终引发 EndRequest 事件。

对于一个ASP.NET应用程序来说,HttpApplication派生与Global.aspx(可以看看我们创建的应用程序都有一个Global.aspx文件),我们可以在Global.aspx文件中对HttpApplication的请求进行定制即注入这19个事件中的某个事件进行逻辑处理操作。在Global.aspx中我们按照"Application_{Event Name}"这样的方法命名进行事件注册。

Event Name就是上面19个事件的名称。比如Application_EndRequest就用于处理Application的EndRequest事件。

HttpModule

ASP.NET拥有一个高度可扩展的引擎,并且能够处理对于不同资源类型的请求。这就是HttpModule。当一个请求转入ASP.net管道时,最终负责处理请求的是与资源相匹配的HttpHandler对象,但是在HttpHandler进行处理之前,ASP.NET先会加载并初始化所有配置的HttpModule对象。HttpModule初始化的时候,会将一些回调事件注入到HttpApplication相应的事件中。所有的HttpModule都实现了IHttpModule接口,该接口有一个有一个Init方法。

 public interface IHttpModule { // Methods void Dispose(); void Init(HttpApplication context); }

看到Init方法呢接受一个HttpApplication对象,有了这个对象就很容易注册HttpApplication中19个事件中的某个事件了。这样当HttpApplication对象执行到某个事件的时候自然就会出发。

HttpHandler

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

 public interface IHttpHandler { // Methods void ProcessRequest(HttpContext context); // Properties bool IsReusable { get; } }

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

ASP.NET MVC 运行机制

好了,上面说了那么多,其实都是给这里做铺垫呢。终于到正题了。先看看下面这张图,描述了MVC的主要经历的管道事件:

上图就是一个完整的mvc应用程序的一个http请求到响应的整个儿所经历的流程。从UrlRoutingModule拦截请求到最终ActionResult执行ExecuteResult方法生成响应。

下面我们就来详细讲解一下这些过程都做了些什么。

UrlRoutingModule

MVC应用程序的入口UrlRoutingModule

-六神源码网