UrlRoutingModel摘要
在机器级别(C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config)的web.config中与如下HttpModule配置
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
该模块代码
---------------
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public class UrlRoutingModule : IHttpModule
{
// Fields
private static readonly object _contextKey = new object();
private static readonly object _requestDataKey = new object();
private RouteCollection _routeCollection;
// Methods
protected virtual void Dispose()
{
}
protected virtual void Init(HttpApplication application)
{
if (application.Context.Items[_contextKey] == null)
{
application.Context.Items[_contextKey] = _contextKey;
application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
}
}
private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
this.PostResolveRequestCache(context);
}
[Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")]
public virtual void PostMapRequestHandler(HttpContextBase context)
{
}
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, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
if (!(routeHandler is StopRoutingHandler))
{
RequestContext requestContext = new RequestContext(context, routeData);
context.Request.RequestContext = requestContext;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
if (httpHandler == null) throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[] { routeHandler.GetType() }));
if (httpHandler is UrlAuthFailureHandler)
{
if (!FormsAuthenticationModule.FormsAuthRequired) throw new HttpException(0x191, SR.GetString("Assess_Denied_Description3"));
UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
}
else
context.RemapHandler(httpHandler);
}
}
}
void IHttpModule.Dispose()
{
this.Dispose();
}
void IHttpModule.Init(HttpApplication application)
{
this.Init(application);
}
// Properties
public RouteCollection RouteCollection
{
get
{
if (this._routeCollection == null) this._routeCollection = RouteTable.Routes;
return this._routeCollection;
}
set
{
this._routeCollection = value;
}
}
}
该模块负责将对应的请求(URL),路由到指定的httpHandler,而httpHandler则由IRouteHandler创建立, 每个Route规则可以指定一个IRouteHandler
MVCRouteHandler代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace System.Web.Mvc {
using System.Web.Routing;
public class MvcRouteHandler : IRouteHandler {
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) {
return new MvcHandler(requestContext);
}
#region IRouteHandler Members
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) {
return GetHttpHandler(requestContext);
}
#endregion
}
}
MVCRouteHandler的任务是创建立MvcHandler
PageRouteHandler代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class PageRouteHandler : IRouteHandler
{
// Fields
private Route _routeVirtualPath;
private bool _useRouteVirtualPath;
// Methods
public PageRouteHandler(string virtualPath) : this(virtualPath, true)
{
}
public PageRouteHandler(string virtualPath, bool checkPhysicalUrlAccess)
{
if (string.IsNullOrEmpty(virtualPath) || !virtualPath.StartsWith("~/", StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(SR.GetString("PageRouteHandler_InvalidVirtualPath"), "virtualPath");
this.VirtualPath = virtualPath;
this.CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
this._useRouteVirtualPath = this.VirtualPath.Contains("{");
}
private bool CheckUrlAccess(string virtualPath, RequestContext requestContext)
{
IPrincipal user = requestContext.HttpContext.User;
if (user == null) user = new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]);
return this.CheckUrlAccessWithAssert(virtualPath, requestContext, user);
}
[SecurityPermission(SecurityAction.Assert, Unrestricted=true)]
private bool CheckUrlAccessWithAssert(string virtualPath, RequestContext requestContext, IPrincipal user)
{
return UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, user, requestContext.HttpContext.Request.HttpMethod);
}
public virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
if (requestContext == null) throw new ArgumentNullException("requestContext");
string substitutedVirtualPath = this.GetSubstitutedVirtualPath(requestContext);
int index = substitutedVirtualPath.IndexOf('?');
if (index != -1) substitutedVirtualPath = substitutedVirtualPath.Substring(0, index);
if (this.CheckPhysicalUrlAccess && !this.CheckUrlAccess(substitutedVirtualPath, requestContext)) return new UrlAuthFailureHandler();
return (BuildManager.CreateInstanceFromVirtualPath(substitutedVirtualPath, typeof(Page)) as Page);
}
public string GetSubstitutedVirtualPath(RequestContext requestContext)
{
if (requestContext == null) throw new ArgumentNullException("requestContext");
if (!this._useRouteVirtualPath) return this.VirtualPath;
VirtualPathData virtualPath = this.RouteVirtualPath.GetVirtualPath(requestContext, requestContext.RouteData.Values);
if (virtualPath == null) return this.VirtualPath;
return ("~/" + virtualPath.VirtualPath);
}
// Properties
public bool CheckPhysicalUrlAccess { get; private set; }
private Route RouteVirtualPath
{
get
{
if (this._routeVirtualPath == null) this._routeVirtualPath = new Route(this.VirtualPath.Substring(2), this);
return this._routeVirtualPath;
}
}
public string VirtualPath { get; private set; }
}
改模块通过BuilerManger来创建Aspx页面对象实例类,创建时会使用机器级的HttpHandlers配置中的页面工厂
<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
调用RouteTable.Routes.MapPageRoute(...)时,会注册一个RouteHandler为PageRouteHanler的Route规则
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens)
{
if (routeUrl == null) throw new ArgumentNullException("routeUrl");
Route item = new Route(routeUrl, defaults, constraints, dataTokens, new PageRouteHandler(physicalFile, checkPhysicalUrlAccess));
this.Add(routeName, item);
return item;
}