MVC学习十四:MVC 路由 Route

一、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对象

原文地址:https://www.cnblogs.com/WarBlog/p/7428356.html