action]", Defaults = new { action = "Index" }, RouteHandler = typeof(MvcRouteHandler null }, RouteHandler = typeof(MvcRouteHandler) }); RouteTable.Routes.Add null }, RouteHandler = typeof(MvcRouteHandler) }); RouteTable.Routes.Add null,sex=(string)null }, RouteHandler = typeof(MvcRouteHandler) }); Home", action = "Index", id = 2, name = "Jimmy",sex="female" }, RouteHandler = typeof(MvcRouteHandler
生成MvcHander 在上面路由匹配的过程中,与匹配路由相关联的MvcRouteHandler ,MvcRouteHandler 实现了IRouteHandler 接口。 所以这里返回MvcRouteHandler至关重要: 那么,MvcRouteHandler从何而来呢? 当我们的请求与路由匹配成功后,自然会返回的是MvcRouteHandler。 好啦,MvcRouteHandler生成了。那么MvcRouteHandler能做什么呢?又做了什么呢? 那我们看看MvcRouteHandler是怎么实现这个GetHttpHandler的呢: 1 public class MvcRouteHandler : IRouteHandler 2 { 3
生成MvcHander 在上面路由匹配的过程中,与匹配路由相关联的MvcRouteHandler ,MvcRouteHandler 实现了IRouteHandler 接口。 所以这里返回MvcRouteHandler至关重要: 那么,MvcRouteHandler从何而来呢? 当我们的请求与路由匹配成功后,自然会返回的是MvcRouteHandler。 好啦,MvcRouteHandler生成了。那么MvcRouteHandler能做什么呢?又做了什么呢? 那我们看看MvcRouteHandler是怎么实现这个GetHttpHandler的呢: 1 public class MvcRouteHandler : IRouteHandler 2 { 3
我们首先需要了解一个类型为MvcRouteHandler的类型。 一、MvcRouteHandler 通过前面的介绍我们知道继承自RouteBase的Route类型具有一个类型为IRouteHandler接口的属性RouteHandler,它主要的用途就是用于根据指定的请求上下文 在默认的情况下,Route的RouteHandler属性是一个MvcRouteHandler对象,如下的代码片断反映了这一点。 (); 9: } 10: } 对于我们这个“迷你版”的ASP.NET MVC框架来说,MvcRouteHandler是一个具有如下定义的类型。 由于RouteData的RouteHandler来源于对应Route对象的RouteHandler,而后者在默认的情况下是一个MvcRouteHandler对象,所以默认情况下用于处理HTTP请求的就是这么一个
,MvcRouteHandler 实现了IRouteHandler 接口。 所以这里返回MvcRouteHandler至关重要: 那么,MvcRouteHandler从何而来呢? 当我们的请求与路由匹配成功后,自然会返回的是MvcRouteHandler。 好啦,MvcRouteHandler生成了。那么MvcRouteHandler能做什么呢?又做了什么呢? 那我们看看MvcRouteHandler是怎么实现这个GetHttpHandler的呢: 1 public class MvcRouteHandler : IRouteHandler 2 { 3
())); routes.Add(new Route("Story/{action}/{name}/{page}", defaults, new MvcRouteHandler( ))); routes.Add(new Route("{controller}/{action}/{id}", defaults, new MvcRouteHandler())) ())); routes.Add(new Route("Story.mvc/{action}/{name}/{page}", defaults, new MvcRouteHandler ())); routes.Add(new Route("{controller}.mvc/{action}/{id}", defaults, new MvcRouteHandler ())); routes.Add(new Route("Default.aspx", defaults, new MvcRouteHandler())); }
如果你使用的是默认的配置,那么请求会传递到MvcRouteHandler,那么请求f附加着HttpContext就会到达Asp.Net MVC的处理中了。 第五阶段:MvcRouteHandler创建Controller 请求到此,其实跟WebForm都是一致的,而后面才出现了一些不同,此时请求才真正的进入System.Web.Mvc控制的领域内。 接着上面讲,请求到了MvcRouteHandler类,而此类的源码如下: namespace System.Web.Mvc { using System.Web.Routing; using System.Web.SessionState; public class MvcRouteHandler : IRouteHandler { private IControllerFactory _controllerFactory; public MvcRouteHandler() { } public MvcRouteHandler
RouteHandler(new RouteHandler(MyRouteHandler.Handler))赋值给Route的target属性,而对于另外两种没有指定的,Route的target属性默认会被指定为MvcRouteHandler B.Handler的选择 当请求进入之后,根据此路由表对该URL进行逐一匹配,并将请求交给匹配到的路由的target(即MvcRouteHandler或RouteHandler),调用 _target.RouteAsync (context); ,在这个方法中,若是MvcRouteHandler会对请求的Controller和Action验证,若验证成功,则对context(是一个RouteContext)的Handler ) { DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler
IControllerPropertyActivator, DefaultControllerPropertyActivator>()); // Route Handlers services.TryAddSingleton<MvcRouteHandler routes = new RouteBuilder(app) { DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler routes = new RouteBuilder(app) { DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler 5.来到Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler.RouteAsync()方法中。 //Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler.RouteAsync public Task RouteAsync(RouteContext context
, StringComparer.OrdinalIgnoreCase)) { result = new RouteData(this, new MvcRouteHandler 当创建RouteData对象,我们需要在handler中传递值,我们使用标准的MvcRouteHandler类,此类指定了controller和 action的值: result = new RouteData (this, new MvcRouteHandler()); 对大多数的MVC应用程序来说,这个类是必须的,因为此类连结了路由系统和controller/action model。 但是你可以实现一个类代替MvcRouteHandler。之后会讲到。 在这个路由实现中,我们路由了任何传递到构造函数的URL请求。 创建自定义路由Handler 在路由中,我们依赖的是MvcRouteHandler,因为它连结了routing system和MVC FrameWork。
MvcRouteHandler 三、ASP.NET路由系统扩展 实例演示:通过自定义Route对ASP.NET路由系统进行扩展 上图所示的作为请求拦截器的HttpModule MvcRouteHandler 通过前面的介绍我们知道对于调用RouteCollection的GetRouteData获得的RouteData对象,其RouteHandler来源于匹配的Route对象。 17: } 18: } ASP.NET MVC的Route对象是通过调用RouteCollection的扩展方法MapRoute方法进行注册的,它对应的RouteHandler是一个类型为MvcRouteHandler 如下面的代码片断所示,MvcRouteHandler用于获取处理当前请求的HttpHandler是一个MvcHandler对象。 1: public class MvcRouteHandler : IRouteHandler 2: { 3: //其他成员 4: public IHttpHandler
= null) { // 再从RouteData中获取MVCRouteHandler IRouteHandler routeHandler = routeData.RouteHandler IHttpHandler 类型实例 映射到IIS HTTP处理管道中 context.RemapHandler(httpHandler); } } } MVCRouteHandler 因为当我们在HttpApplication的第一个管道事件,使用MapRoute()方法注册路由的时候,已经通过Route类的构造函数把MvcRouteHandler注入到路由中了。 刚刚我们知道MvcRouteHandler是用来生成实现IHttpHandler接口的MvcHandler,那么我们继续从UrlRoutingModule的源码可以看到,通过HttpHandler的GetHttpHandler 换句话说,MvcRouteHandler把请求交给了MvcHandler去做请求处理管道中后续事件的处理操作了。 ?
action]/[id]", Defaults = new { action = "Index", id = (string)null }, RouteHandler = typeof(MvcRouteHandler Defaults = new { controller = "Home", action = "Index", id = (string)null }, RouteHandler = typeof(MvcRouteHandler
在GetRouteData方法中,除了根据查询字符解析并初始化Controller和Action名称之外,还将RouteHandler指定为MvcRouteHandler。 而MvcRouteHandler得GetHttpHandler方法直接返回的是根据RequestContext创建的MvcHandler对象。 action = httpContext.Request.QueryString["action"]; 10: IRouteHandler routeHandler = new MvcRouteHandler 12: } 13: return null; 14: } 15: } 16: 17: public class MvcRouteHandler
ASP.NETRouting路由系统的整个运行机制有了一个基本的了解;当我们能清楚的知道Url是如何被解析成RouteData对象时,下面就是这些路由数据是如何被后面的应用框架所使用的,而通往应用框架的入口是MvcRouteHandler 并且成功的获取到应用框架配置的路由数据后,下面将进入IHttpHandler接口,而这个接口真是我们初始化RouteData对象时设定的应用框架入口,ASP.NETMVC所使用的是MvcHandler对象; MvcRouteHandler 对象是UrlRoutingModule和MvcHandler对象的连接器,只有MvcRouteHandler对象能成功执行后,方能进入到MvcHandler对象中,后续的一切运转才能顺利执行; 2】ASP.NETMVC
对于ASP.NET MVC应用来说,RouteData的RouteHandler属性类型为MvcRouteHandler,体现在MvcRouteHandler类型上关于HttpHandler的提供机制基本上 MvcRouteHandler维护着一个ControllerFactory对象,该对象可以在构造函数中指定,如果没有显示指定则直接通过调用当前ControllerBuilder的GetControllerFactory 1: public class MvcRouteHandler : IRouteHandler 2: { 3: private IControllerFactory _controllerFactory ; 4: public MvcRouteHandler(): this(ControllerBuilder.Current.GetControllerFactory()) 5: { } 6: public MvcRouteHandler(IControllerFactory controllerFactory) 7: { 8:
UrlRoutingModule的时候,UrlRoutingModule取出请求中的Controller、Action等RouteData信息,与路由表中的所有规则进行匹配,若匹配,把请求交给IRouteHandler,即MVCRouteHandler = null) { // 再从RouteData中获取MVCRouteHandler IRouteHandler routeHandler = routeData.RouteHandler 这里我省略了ASP.NET MVC源码中MvcRouteHandler生成MvcHandler的步骤,直接丢给MvcHandler处理。
将解析出的信息交给一个MvcRouteHandler对象进行处理,MvcHttpHandler中存在以个ControllerFactory成员,如果构造函数中没有提供一个实现IControllerFactory
接下来用简图表示Controller激活的基本过程,请求到来后,HttpModule进行拦截,通过MvcRouteHandler调用GetHttpHandler方法找到对应HttpHandler处理类,
RouteData GetRouteData(System.Web.HttpContextBase httpContext) { var data = new RouteData(this, new MvcRouteHandler ,返回null,让匹配继续进行 return null; //至此可以肯定是我们要处理的URL了 var data = new RouteData(this, new MvcRouteHandler