MVC路由解析---IgnoreRoute


文章引導

              MVC路由解析---IgnoreRoute 

              MVC路由解析---MapRoute 

              MVC路由解析---UrlRoutingModule  

              Area的使用

              Area--->AreaRegister.RegisterAllArea()與Area區域的解析(一)

引言

Reflector源碼反編譯工具軟件是必備

一.由路由注冊開始

嚴格的說Route不只屬於MVC,MVC所有的請求都是通過路由規則去映射的,所以MVC的頭等大事就是路由規則的注冊。規則的注冊時在Global.asax的Application_Start事件里注冊,以下是默認的路由注冊代碼

 1 public class RouteConfig
 2     {
 3         public static void RegisterRoutes(RouteCollection routes)
 4         {
 5             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 6 
 7             routes.MapRoute(
 8                 name: "Default",
 9                 url: "{controller}/{action}/{id}",
10                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
11             );
12         }
13     }
View Code

我們這篇文章的講述內容以routes.IgnoreRoute("{resource}.axd/{*pathInfo}")深入學習

二.Application_Start的傳參

               IgnoreRoute的方法參數傳入是由Application_Start的RouteConfig.RegisterRoutes(RouteTable.Routes)傳入。但是RouteConfig類中RegisterRoutes的參數卻為RouteCollection,好吧,我們的工作開始了。我們先來看RouteTable有什么深處含義。

               RouteTable源碼:                  

 1         private static RouteCollection _instance;
 2         static RouteTable()
 3         {
 4             _instance = new RouteCollection();
 5         }
 6 
 7         public static RouteCollection Routes
 8         {
 9             get { return _instance; }
10         }
View Code

                RouteTable是一個單例模式(如果不知道這個模式的同學可以去學習一下設計模式),Routes是一個公共的靜態屬性,屬性的類型是RouteCollection。這也是RouteConfig類中的RegisterRoutes的參數為RouteCollection的緣故。

                總結:RouteTable只有一個職責,就是構建一個靜態單例RouteCollection,RouteCollection是一個泛型類:Collection<RouteBase>。這個RouteCollection用來保存路由規則的集合。

三.RouteCollection的IgnoreRoute

                廢話不多說,上源碼(這個時候就是Reflection的厲害之處了):         

public class RouteCollection:Collection<RouteBase>
    {
        private Dictionary<string, RouteBase> _namedMap;
        private ReaderWriterLock _rwLock;

        public RouteCollection()
        {
            _namedMap = new Dictionary<string, RouteBase>(StringComparer.OrdinalIgnoreCase);
            _rwLock = new ReaderWriterLock();
        }

        public void Ignore(string url)
        {
            Ignore(url, null);
        }
        public void Ignore(string url,object constraints)
        {
            if (url == null)
            {
                throw new ArgumentNullException("url");
            }
            IgnoreRouteInternal item = new IgnoreRouteInternal(url)
            {
                Constraints=new System.Web.Routing.RouteValueDictionary(constraints)
            };
            base.Add(item);
        }
    }

                上源碼中RouteCollection是一個泛型繼承了RouteBase的集合類Collection。

四.IgnoreRouteInternal

                為了更好的深入了解,我們繼續深入下去,現在看下IgnoreRouteInternal:

    public sealed class IgnoreRouteInternal:Route
    {
        public IgnoreRouteInternal(string url):base(url,new StopRoutingHandler())
        {

        }
    }

                可以看到,這是一個密封類,是不允許被繼承的,但他卻繼承了Route,Route class是繼承了RouteBase class。IgnoreRouteInternal有參構造函數調用的是Route的有參構造函數。

五.StopRoutingHandler

                我們先來拆開StopRoutingHandler 看一下:        

public class StopRoutingHandler:System.Web.Routing.IRouteHandler
    {
        IHttpHandler System.Web.Routing.IRouteHandler.GetHttpHandler(System.Web.Routing.RequestContext requestContext)
        {
            return this.GetHttpHandler(requestContext);
        }
        protected virtual IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext req)
        {
            throw new NotSupportedException();
        }
    }

                StopRoutingHandler是個特殊的RouteHandler對象,它的作用只是告訴UrlRouteModule,雖然某個規則匹配成功了,但是也還是當什么沒有發生,說白了,我們需要去忽略一些規則。

                我們來看一下一個如何被忽略的例子,阻止路由處理.axd文件的請求。

                    routes.Add(new Route("{resource}/.axd/{*pathInfo}",new StopRoutingHandler()));

六.IRouteHandler

                打打雞血,我們繼續來拆解IRouteHandler     

    //
    // 摘要:
    //     定義類必須實現才能處理匹配路由模式的請求的協定。
    [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
    public interface IRouteHandler
    {
        //
        // 摘要:
        //     提供處理請求的對象。
        //
        // 參數:
        //   requestContext:
        //     一個對象,封裝有關請求的信息。
        //
        // 返回結果:
        //     一個處理請求的對象。
        IHttpHandler GetHttpHandler(RequestContext requestContext);

                IRouteHandler接口方法GetHttpHandler必須返回一個實現了IHttpHandler的信息,接受的參數類型為RequestContext,看到這個RequestContext,大家就會眼前一亮。這個是一個非常重要的點。

                此處引入一位大神的Blog內容:深入解析路由系統架構原理 ----->https://www.cnblogs.com/Leo_wl/p/3380570.html

七.Route

                我們回到第四步,public IgnoreRouteInternal(string url):base(url,new StopRoutingHandler())我們來看看Route的構造函數     

public class Route:RouteBase
    {
        private string _url;

        public System.Web.Routing.IRouteHandler RouteHandler { get; set; }
        public Route(string url,System.Web.Routing.IRouteHandler routeHandler)
        {
            this._url = url;
            RouteHandler = routeHandler;
        }

        public System.Web.Routing.RouteValueDictionary Constraints { get; set; }
    }

 

八.base.Add(item)

                RouteCollection是一個集合類,默認集合,將IgnoreRouteInternal放入集合。

 

思維導圖:

                

 System.Web.dll文件反編譯后的源碼:System.Web.dll

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM