ASP.NET MVC深度接触:ASP.NET MVC请求生命周期

这篇博文的目的旨在详细描述ASP.NET MVC 请求从开始到结束的每一个过程。我希望能理解在浏览器输入URL 并敲击回车来请求一个ASP.NET MVC 网站的页面之后发生的任何事情。

         为什么需要关心这些?有两个原因。首先是因为ASP.NET MVC 是一个扩展性非常强的框架。例如,我们可以插入不同的ViewEngine 来控制网站内容呈现的方式。我们还可以定义控制器生成和分配到某个请求的方式。因为我想发掘任何ASP.NET MVC 页面请求的扩展点,所以我要来探究请求过程中的一些步骤。

         其次,我对测试驱动开发佷感兴趣。要为控制器写单元测试,我们就必须理解控制器的依赖项。在写测试的时候,我需要使用诸如Typemock Isolator 或Rhino Mocks 的Mock 框架来模拟某些对象。如果不了解页面请求生命周期就不能进行有效的模拟。

两个警告

         首先,要给大家两个警告。

         第一个警告:我在ASP.NET MVC Preview2 对外发布之后写了此文。ASP.NET MVC 框架在Beta 前还会变化很大。因此,我在此文中描述的任何东西都会在几个月后不再有效。因此,如果你在2008 年5 月之后读此文的话,不要相信任何你读到的东西。

         第二,此文不是ASP.NET MVC 的概览。我只是枯草地介绍了ASP.NET MVC 请求的生命周期。好了,别说我没有提醒你。

生命周期步骤概览

         当我们对ASP.NET MVC 网站发出一个请求的时候,会发生5 个主要步骤:

1 、步骤1 ——创建RouteTable

         当ASP.NET 应用程序第一次启动的时候才会发生第一步。RouteTable 把URL 映射到Handler 。

2 、步骤2 ——UrlRoutingModule 拦截请求

         第二步在我们发起请求的时候发生。UrlRoutingModule 拦截了每一个请求并且创建和执行合适的Handler 。

3 、步骤3 ——执行MvcHandler

         MvcHandler 创建了控制器,并且把控制器传入ControllerContext ,然后执行控制器。

4 、步骤4 ——执行控制器

         控制器检测要执行的控制器方法,构建参数列表并且执行方法。

5 、步骤5 ——调用RenderView 方法

         大多数情况下,控制器方法调用RenderView() 来把内容呈现回浏览器。Controller.RenderView() 方法把这个工作委托给某个ViewEngine 来做。

         让我们详细研究每一个步骤。

步骤1 ——创建RouteTable

         当我们请求普通ASP.NET 应用程序页面的时候,对于每一个页面请求都会在磁盘上有这样一个页面。例如,如果我们请求一个叫做SomePage.aspx 的页面,在WEB 服务器上就会有一个叫做SomePage.aspx 的页面。如果没有的话,会得到一个错误。

         从技术角度说,ASP.NET 页面代表一个类,并且不是普通类。ASP.NET 页面是一个Handler 。换句话说,ASP.NET 页面实现了IhttpHandler 接口并且有一个ProcessRequest() 方法用于在请求页面的时候接受请求。ProcessRequest() 方法负责生成内容并把它发回浏览器。

         因此,普通ASP.NET 应用程序的工作方式佷简单明了。我们请求页面,页面请求对应磁盘上的某个页面,这个页面执行ProcessRequest() 方法并把内容发回浏览器。

         ASP.NET MVC 应用程序不是以这种方式工作的。当我们请求一个ASP.NET MVC 应用程序的页面时,在磁盘上不存在对应请求的页面。而是,请求被路由转到一个叫做控制器的类上。控制器负责生成内容并把它发回浏览器。

         当我们写普通ASP.NET 应用程序的时候,会创建很多页面。在URL 和页面之间总是一一对应进行映射。每一个页面请求对应相应的页面。

         相反,当我们创建ASP.NET MVC 应用程序的时候,创建的是一批控制器。使用控制器的优势是可以在URL 和页面之间可以有多对一的映射。例如,所有如下的URL 都可以映射到相同的控制器上。

http://MySite/Products/1

http://MySite/Products/2

http://MySite/Products/3

         这些URL 映射到一个控制器上,通过从URL 中提取产品ID 来显示正确的产品。这种控制器方式比传统的ASP.NET 方式更灵活。控制器方式可以产品更显而易见的URL 。

         那么,某个页面请求是怎么路由到某个控制器上的呢?ASP.NET MVC 应用程序有一个叫做路由表(Route Table )的东西。路由表映射某个URL 到某个控制器上。

         一个应用程序有一个并且只会有一个路由表。路由表在Global.asax 文件中创建。清单1 包含了在使用Visual Studio 新建ASP.NET MVC Web 应用程序时默认的Global.asax 文件。

清单1 – Global.asax

using System; 
using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using System.Web.Mvc; 6: using System.Web.Routing; 7: 8: namespace TestMVCArch 9: { 10: public class GlobalApplication : System.Web.HttpApplication 11: { 12: public static void RegisterRoutes(RouteCollection routes) 13: { 14: // Note: Change the URL to "{controller}.mvc/{action}/{id}" to enable 15: // automatic support on IIS6 and IIS7 classic mode 16: 17: routes.Add(new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 18: { 19: Defaults = new RouteValueDictionary(new { action = "Index", id = "" }), 20: }); 21: 22: routes.Add(new Route("Default.aspx", new MvcRouteHandler()) 23: { 24: Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 25: }); 26: } 27: 28: protected void Application_Start(object sender, EventArgs e) 29: { 30: RegisterRoutes(RouteTable.Routes); 31: } 32: } 33: }

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。