做ASP.NET WebForm開發都知道,ASP.NET有復雜的生命周期,學習ASP.NET MVC就要深入理解它的生命周期。今天從CodePlex上下載了ASP.NET Preview 2 的 源代碼,還有兩個程序集Routing與Abstractions並未發布,不過這兩個程序集的 類並不多,可以用NET反編譯工具 Reflector解開來看看,可惜這兩個程序集用的 是VS2008使用.net 3.5開發的,用了c# 3.0的很多特性,Reflector反編譯不完全 。
ASP.NET MVC通過HttpModule(UrlRoutingModule)開始他的執行流程
<httpModules>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing" />
</httpModules>
代碼如下:
namespace System.Web.Routing
{
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Web;
using System.Web.Resources;
[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission (SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public class UrlRoutingModule : IHttpModule
{
private static readonly object _requestDataKey = new object();
private System.Web.Routing.RouteCollection _routeCollection;
protected virtual void Dispose()
{
}
protected virtual void Init(HttpApplication application)
{
application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
application.PostMapRequestHandler += new EventHandler (this.OnApplicationPostMapRequestHandler);
}
private void OnApplicationPostMapRequestHandler(object sender, EventArgs e)
{
HttpContextBase context = new HttpContextWrapper2(((HttpApplication) sender).Context);
this.PostMapRequestHandler(context);
}
private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
HttpContextBase context = new HttpContextWrapper2(((HttpApplication) sender).Context);
this.PostResolveRequestCache(context);
}
public virtual void PostMapRequestHandler(HttpContextBase context)
{
RequestData data = (RequestData) context.Items[_requestDataKey];
if (data != null)
{
context.RewritePath (data.OriginalPath);
context.Handler = data.HttpHandler;
}
}
public virtual void PostResolveRequestCache(HttpContextBase context)
{
RouteData routeData = this.RouteCollection.GetRouteData(context);
if (routeData != null)
{
IRouteHandler routeHandler = routeData.RouteHandler;
if (routeHandler == null)
{
throw new InvalidOperationException(string.Format (CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
}
RequestContext requestContext = new RequestContext(context, routeData);
IHttpHandler httpHandler = routeHandler.GetHttpHandler (requestContext);
if (httpHandler == null)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
}
RequestData data2 = new RequestData();
data2.OriginalPath = context.Request.Path;
data2.HttpHandler = httpHandler;
context.Items [_requestDataKey] = data2;
context.RewritePath ("~/UrlRouting.axd");
}
}
void IHttpModule.Dispose()
{
this.Dispose();
}
void IHttpModule.Init (HttpApplication application)
{
this.Init(application);
}
public System.Web.Routing.RouteCollection RouteCollection
{
get
{
if (this._routeCollection == null)
{
this._routeCollection = RouteTable.Routes;
}
return this._routeCollection;
}
set
{
this._routeCollection = value;
}
}
}