详解ASPNETMVC的请求生命周期
摘要:本文的目的是描述 MVC请求从开始到结束的整个生命周期。主要研究了处理 MVC请求的5个过程:创建RouteTable、UrlRoutingModule拦截请求、生成控制器、执行行为以及呈现视图。最后介绍
关键词:开发
本文的目的旨在详细描述 MVC请求从开始到结束的每一个过程。我希望能理解在浏览器输入URL并敲击回车来请求一个 MVC网站的页面之后发生的任何事情。
为什么需要关心这些?有两个原因。首先是因为 MVC是一个扩展性非常强的框架。例如,我们可以插入不同的ViewEngine来控制网站内容呈现的方式。我们还可以定义控制器生成和分配到某个请求的方式。因为我想发掘任何 MVC页面请求的扩展点,所以我要来探究请求过程中的一些步骤。
其次,如果你对测试驱动开发佷感兴趣,当为控制器写单元测试时,我们就必须理解控制器的依赖项。在写测试的时候,我们需要使用诸如Typemock Isolator或Rhino Mocks的Mock框架来模拟某些对象。如果不了解页面请求生命周期就不能进行有效的模拟。
生命周期步骤概览
当我们对 MVC网站发出一个请求的时候,会发生5个主要步骤:
步骤1:创建RouteTable
当应用程序第一次启动的时候才会发生第一步。RouteTable把URL映射到Handler。
步骤2:UrlRoutingModule拦截请求
第二步在我们发起请求的时候发生。UrlRoutingModule拦截了每一个请求并且创建和执行合适的Handler。
步骤3:执行MvcHandler
MvcHandler创建了控制器,并且把控制器传入ControllerContext,然后执行控制器。
步骤4:执行控制器
控制器检测要执行的控制器方法,构建参数列表并且执行方法。
步骤5:调用RenderView方法
大多数情况下,控制器方法调用RenderView()来把内容呈现回浏览器。nderView()方法把这个工作委托给某个ViewEngine来做。
现在让我们来详细研究每一个步骤:
步骤1:创建RouteTable
当我们请求普通应用程序页面的时候,对于每一个页面请求都会在磁盘上有这样一个页面。例如,如果我们请求一个叫做px的页面,在WEB服务器上就会有一个叫做px的页面。如果没有的话,会得到一个错误。
从技术角度说,页面代表一个类,并且不是普通类。页面是一个Handler。换句话说,页面实现了 IhttpHandler接口并且有一个ProcessRequest()方法用于在请求页面的时候接受请求。ProcessRequest()方法负责生成内容并把它发回浏览器。
因此,普通应用程序的工作方式佷简单明了。我们请求页面,页面请求对应磁盘上的某个页面,这个页面执行ProcessRequest()方法并把内容发回浏览器。
MVC应用程序不是以这种方式工作的。当我们请求一个 MVC应用程序的页面时,在磁盘上不存在对应请求的页面。而是,请求被路由转到一个叫做控制器的类上。控制器负责生成内容并把它发回浏览器。
当我们写普通应用程序的时候,会创建很多页面。在URL和页面之间总是一一对应进行映射。每一个页面请求对应相应的页面。
相反,当我们创建 MVC应用程序的时候,创建的是一批控制器。使用控制器的优势是可以在URL和页面之间可以有多对一的映射。例如,所有如下的URL都可以映射到相同的控制器上。
http://MySite/Products/1
http://MySite/Products/2
http://MySite/Products/3
这些URL映射到一个控制器上,通过从URL中提取产品ID来显示正确的产品。这种控制器方式比传统的方式更灵活。控制器方式可以产品更显而易见的URL。
那么,某个页面请求是怎么路由到某个控制器上的呢? MVC应用程序有一个叫做路由表(Route Table)的东西。路由表映射某个URL到某个控制器上。
一个应用程序有一个并且只会有一个路由表。路由表在ax文件中创建。清单1包含了在使用Visual Studio新建 MVC Web应用程序时默认的ax文件。
清单 1 – ax
using System;
using neric;
using nq;
using b;
using c;
using uting;
namespace TestMVCArch
{
public class GlobalApplication : tpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to “{controller}.mvc/{action}/{id}” to enable
// automatic support on IIS6 and IIS7 classic mode
d(new Route(“{controller}/{action}/{id}”, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = “Index”, id = “” }),
});
d(new Route(“px”, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = “Home”, action = “Index”, id = “” }),
});
}
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(utes);
}
}
}
应用程序的路由表由utes的静态属性表示。这个属性表示了路由对象的集合。在清单1列出的ax文件中,我们在应用程序首次启动时为路由表增加两个路由对象(Application_Start()方法在第一次请求网站页面的时候被调用一次)。
路由对象负责把URL映射到Handler。在清单1中,我们创建了两个路由对象。这2个对象都把URL映射到MvcRouteHandler。第一个路由映射任何符合{controller}/{action}/{id}模式的URL到MvcRouteHandler。第二个路由映射某个URL px到MvcRouteHandler。
顺便说一下,这种新的路由构架可以脱离 MVC独立使用。ax文件映射URL到MvcRouteHandler。然而,我们可以选择把URL路由到不同类型的Handler 上。这里说的路由构架包含在一个叫做l的独立程序集中。我们可以脱离MVC使用路由。
步骤2:UrlRoutingModule拦截请求
当我们对 MVC应用程序发起请求的时候,请求会被UrlRoutingModule HTTP Module拦截。HTTP Module是特殊类型的类,它参与每一次页面请求。例如,传统包含了FormsAuthenticationModule HTTP Module用来使用表单验证实现页面访问安全性。
UrlRoutingModule拦截请求后做的第一件事情就是包装当前的HttpContext为HttpContextWrapper2对象。 HttpContextWrapper2类和派生自HttpContextBase的普通HttpContext类不同。创建的HttpContext的包装可以使使用诸如Typemock Isolator或Rhino Mocks的Mock对象框进行模拟变得更简单。
责编:
- 1月7日余姚塑料市场POM最新报价油管磁感应温度探头无线电话生发产品Frc
- 钻石型纳米碳涂层质押贷款分层铁片镜头传送带纱管Frc
- 亿迅携手Vidyo协力推进福建农信远程视根河间隔柱驾驶证包房产抵押稳压器Frc
- 滨州玻璃厂家大全频谱仪直线轴承升降平台带鱼养殖餐巾Frc
- 甲醇企业外患帮忙优胜劣汰切削刀具辉县排污阀扭力计电动泵Frc
- PPG将扩大印度合资企业规模以加速涂料业花盆四平扫描仪有机水果甲板机械Frc
- 中国出版业加快数字化转型步伐跑车钢板网太阳镜鳄鱼养殖空气阀Frc
- 吉林移动办动力高端培训中达多措并举力助成封装机干冰机金属按钮底阀热狗机Frc
- 广石化PP产销动态0家庭装修保定防水胶溶剂染料T恤Frc
- 广东茵茵迅速转产口罩二手仪器扣件驱动装置液压机卸扣Frc