一、MVC路由(Route)是什么?
MVC路由(Route)可以理解规定用户访问网站方式的配置文件,就例如:我们在访问普通页面时http://xxxx/web/xx.aspx,但在MVC中我们的访问方式有可能是:http://xxx/控制器名/Action方法名(这个是默认的路由规则)
那问题就来了,为什么Route可以改变我们的访问方式的呢?
二、Route的原理
1.页面生命周期
1.1.通过HttpRuntime创建HttpContext(包含Request/Response/Session/Application ...)
1.2.通过HttpApplicationFactory
①网站第一次访问时,调用Global文件里的Application_Statr方法
②获取Global文件里的类型作为网站的HttpApplication
③返回一个HttpApplication类或子类对象
1.3.HttpAppliction对象的ProcessRequest会去执行管道事件
在1.2.中会执行Application_Start方法,MVC中的Application_Start
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由表 BundleConfig.RegisterBundles(BundleTable.Bundles); }
这个就是MVC中的路由表(Route)
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}",//Stu/Modify/1 defaults: new { controller = "Stu", action = "RazorView", id = UrlParameter.Optional } ); } }
通过routes.MapRoute把路由信息封装起来
封装的路由信息是什么样子的呢,通过反编译System.Web.Mvc.dll程序集找到RouteCollectionExtensions
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } Route item = new Route(url, new MvcRouteHandler()) { Defaults = CreateRouteValueDictionary(defaults), Constraints = CreateRouteValueDictionary(constraints), DataTokens = new RouteValueDictionary() }; if ((namespaces != null) && (namespaces.Length > 0)) { item.DataTokens["Namespaces"] = namespaces; } routes.Add(name, item); return item; }
到这里我们能看到的是把路由表中的数据得到,那是如何使用的
2.使用Route
2.1.查看C:WindowsMicrosoft.NETFrameworkv4.0.30319Config这个路径下的web.config文件中的
<httpModules> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" /> <add name="Session" type="System.Web.SessionState.SessionStateModule" /> <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" /> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /> <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /> <add name="RoleManager" type="System.Web.Security.RoleManagerModule" /> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" /> <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" /> <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" /> <add name="Profile" type="System.Web.Profile.ProfileModule" /> <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" /> <add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </httpModules>
根据反编译搜索UrlRoutingModule
读取配置文件里的系统配置文件及用户配置的httpModule对象,循环调用Init方法,为Application对象里的某些事件注册方法(请求管道里的事件注册用户的代码)
总结:
管道事件的第7个事件(PostResolveRequestCache):根据上下文匹配路由表取得路由数据并存入MVCHandler,然后把MVCHandler存入HttPContext
1.判断浏览器URL是否有服务器文件
如果有,则停止方法,执行后面管道事件(因为js/css/jpg等不需要经过MVC处理)
2.根据URL到路由表里查找匹配规则的路由
2.1.遍历 路由表(RouteCollection)里所有路由,元素类型为Route并调用每个Route对象的GetRouteData方法
3.将MVCHandler存入HttPContext对象