一、介绍
我们做开发的,尤其是做微软技术栈的,有一个方向是跳不过去的,那就是MVC开发。我相信大家,做ASP.NET MVC 开发有的有很长时间,当然,也有刚进入这个行业的。无论如何,如果有人问你,你知道ASP.NET MVC的生命周期吗?你知道它的来世今生吗?你知道它和 ASP.NET WEBFORM 有什么区别吗?估计,这些问题,有很多人会答不上来,或者说不清楚。今天,我就把我的理解写出来,也是对我自己学习的一次回顾和总结吧。当然,由于本人能力有限,在写的过程中也可能会有一些错误,希望大家多多包涵,当然,更希望大家能不灵赐教,我们共同进步。
在开始之前,我们先来说说,ASP.NET Web Form 和 Asp.net MVC 有什么区别,这里说的区别,当然是本质区别,不是适用语法那个层次的。其实,说起来,ASP.NET WEB FORM 和 ASP.NET MVC 它们两个没有本质区别,使用的都是ASP.NET WEB FORM 的管道处理模型,ASP.NET MVC 也是通过扩展 IHttpModule 和 IHttpHandler 来实现的,都是基于 ASP.NET 的 HttpApplication 的管道处理模型扩展的,在这个层面来说,它们是一样的。当然,大家不要抬杠,我说的本质区别都是在这个方面,不同意的勿喷。
有人会问,ASP.NET MVC 和 ASP.NET WEBAPI 它们会有什么不同吗?好像 WebAPi 能做的,WebMVC都可以完成,第一眼看上去,好像是这样,但是它们有着本质的不同。WebAPI 的处理管道是重新写过的,不是基于 HTTPApplication 管道扩展的。ASP.NET WEB API 类似专人做专事,它的管道处理模型更高效,并且有了 Restfull 的概念。当然,大家如何向了解更细的内容,就需要看源码了。或再说回来,到了 NET CORE 时代,二者又融合管道了。
二、MVC生命周期详述
1、我们既然要说 ASP.NET MVC的生命周期,为了给大家一个整体印象,俗话说,文不如图,我就贴一张图,按着箭头走,相信大家也会不能理解。
2、上图很简单,大家按着箭头走,也能理解的差不多。以下是按着我的理解,划分了4个模块。
(1)、路由模块
RouteBase 是对路由规则的抽象,也就是说,一个 RouteBase 对象,也就代表了一个条 路由规则。在 ASP.NET MVC 中,有一个唯一的子类实现就是 Route ,它同样也是路由规则的代表。我们有了路由规则,一定会把这个规则存放在一个地方,这个地方保存了很多路由规则,这个地方就是 RouteCollection,中文叫“路由集合”,因为这个集合里面包含的就是 RouteBase 对象。
RouteCollection 就是路由集合,用于保存路由规则对象,它的定义形式:
1 [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
2 public class RouteCollection : Collection<RouteBase>
3 {
4 private class ReadLockDisposable : IDisposable
5 {
6 private ReaderWriterLockSlim _rwLock;
7
8 public ReadLockDisposable(ReaderWriterLockSlim rwLock)
9 {
10 this._rwLock = rwLock;
11 }
12
13 void IDisposable.Dispose()
14 {
15 this._rwLock.ExitReadLock();
16 }
17 }
18 ......
RouteTable 就是路由表,其实它和 RouteCollection 是一样的。
1 public class RouteTable
2 {
3 private static RouteCollection _instance = new RouteCollection();
4
5 public static RouteCollection Routes
6 {
7 get
8 {
9 return RouteTable._instance;
10 }
11 }
12 }
在ASP.NET MVC处理管线中的第一站就是路由模块。当请求到达路由模块后,ASP.NET MVC 框架就会根据 RouteTable 中配置的路由模板来匹配当前请求以获得对应的 Controller 和 Action 信息。具体的匹配过程就是有UrlRoutingModule(
System.Web.Routing.UrlRoutingModule)来实现的。如果遇到一个匹配的规则,就会立刻跳出下面的配置。也就是说,配置过程是有顺序的,如果有一个匹配,后面就算有匹配的也不会执行的。
1 namespace System.Web.Routing
2 {
3 [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
4 public class UrlRoutingModule : IHttpModule
5 {
6 private static readonly object _contextKey = new object();
7
8 private static readonly object _requestDataKey = new object();
9
10 private RouteCollection _routeCollection;
11
12 public RouteCollection RouteCollection
13 {
14 get
15 {
16 if (this._routeCollection == null)
17 {
18 this._routeCollection = RouteTable.Routes;
19 }
20 return this._routeCollection;
21 }
22 set
23 {
24 this._routeCollection = value;
25 }
26 }
27
28 protected virtual void Dispose()
29 {
30 }
31
32 protected virtual void Init(HttpApplication application)
33 {
34 if (application.Context.Items[UrlRoutingModule._contextKey] != null)
35 {
36 return;
37 }
38 application.Context.Items[UrlRoutingModule._contextKey] = UrlRoutingModule._contextKey;
39 application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
40 }
41
42 private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
43 {
44 HttpApplication httpApplication = (HttpApplication)sender;
45 HttpContextBase context = new HttpContextWrapper(httpApplication.Context);
46 this.PostResolveRequestCache(context);
47 }
48
49 [Obsolete("This method is obsolete. Override the Init method to use the PostMapRe