ASP.NET MVC路由匹配檢測組件RouteDebug.dll

來源:互聯網
上載者:User

  以前使用RouteMonitor.dll進行MVC路由檢測URL路徑的映射匹配情況。由於公司電腦沒有此組件,所以上網搜了下,結果才發現RouteMonitor.dll已經將名稱改為了RouteDebug.dll 。具體參閱 官方網站。 :http://files.cnblogs.com/Capricornus/RouteDebug-Binary.zip

 

  使用方法:

  1. 在MVC項目中添加引用此組件

  2. 在全域應用程式類Global.asax.cs中設定代碼
  

        protected void Application_Start()        {            RegisterRoutes(RouteTable.Routes);            RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);            //以前RouteMonitor方式            //RouteMonitor.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);        }

  3.匹配路由如:

  

  

 我們可以使用Reflector反編譯這個RouteDebugger.dll組件,查看一下原理。

RouteDebug中包含了DebugHttpHandler、DebugRoute、DebugRouteHandler、RouteDebugger這4個類。

首先從我們調用RouteDebug.RouteDebugger.RewriteRoutesForTesting的著手。

 RouteDebugger類:

public static class RouteDebugger{    // Methods    public static void RewriteRoutesForTesting(RouteCollection routes)    {        using (routes.GetReadLock())        {            bool flag = false;            foreach (RouteBase base2 in routes)            {                Route route = base2 as Route;                if (route != null)                {                    route.RouteHandler = new DebugRouteHandler();                }                if (route == DebugRoute.Singleton)                {                    flag = true;                }            }            if (!flag)            {                routes.Add(DebugRoute.Singleton);            }        }    }}

首先,整個代碼是使用System.Web.Routing命名空間下的RouteCollection.GetReadLock()鎖定的,提供一個對象,用於管理在從集合中檢索對象時的執行緒安全性;然後遍曆我們傳過來的路由集合參數。用RouteDebug中的DebugRouteHandler去替換原有RouteHandler,以便改變Http處理常式的方向,接著將Singletion屬性的值添加到路由結合中。

 DebugRoute類:

public class DebugRoute : Route{    private static DebugRoute singleton = new DebugRoute();    private DebugRoute() : base("{*catchall}", new DebugRouteHandler())    {    }    public static DebugRoute Singleton    {        get        {            return singleton;        }    }}

 DebugRoute繼承與Route類,建構函式實現了構造可捕獲所有URL地址的Route。

 DebugRouteHandler路由處理常式類:

public class DebugRouteHandler : IRouteHandler{    // Methods    public IHttpHandler GetHttpHandler(RequestContext requestContext)    {        DebugHttpHandler handler = new DebugHttpHandler();        handler.RequestContext = requestContext;        return handler;    }}

 實現IHttpHanlder介面的執行個體化對象,傳入了一個RequestContext對象執行個體。

DebugHttpHandler類:

public class DebugHttpHandler : IHttpHandler{    [CompilerGenerated]    private RequestContext <RequestContext>k__BackingField;    private static string FormatRouteValueDictionary(RouteValueDictionary values)    {        if ((values == null) || (values.Count == 0))        {            return "(null)";        }        string str = string.Empty;        foreach (string str2 in values.Keys)        {            str = str + string.Format("{0} = {1}, ", str2, values[str2]);        }        if (str.EndsWith(", "))        {            str = str.Substring(0, str.Length - 2);        }        return str;    }    public void ProcessRequest(HttpContext context)    {        string str = string.Empty;        if (context.Request.QueryString.Count > 0)        {            RouteValueDictionary dictionary = new RouteValueDictionary();            foreach (string str2 in context.Request.QueryString.Keys)            {                dictionary.Add(str2, context.Request.QueryString[str2]);            }            VirtualPathData virtualPath = RouteTable.Routes.GetVirtualPath(this.RequestContext, dictionary);            if (virtualPath != null)            {                str = "<p><label>Generated URL</label>: ";                str = str + "<strong style=\"color: #00a;\">" + virtualPath.VirtualPath + "</strong>";                Route route = virtualPath.Route as Route;                if (route != null)                {                    str = str + " using the route \"" + route.Url + "\"</p>";                }            }        }        string format = "<html>\r\n<head>\r\n    <title>Route Tester</title>\r\n    <style>\r\n        body, td, th {{font-family: verdana; font-size: small;}}\r\n        .message {{font-size: .9em;}}\r\n        caption {{font-weight: bold;}}\r\n        tr.header {{background-color: #ffc;}}\r\n        label {{font-weight: bold; font-size: 1.1em;}}\r\n        .false {{color: #c00;}}\r\n        .true {{color: #0c0;}}\r\n    </style>\r\n</head>\r\n<body>\r\n<h1>Route Tester</h1>\r\n<div id=\"main\">\r\n    <p class=\"message\">\r\n        Type in a url in the address bar to see which defined routes match it. \r\n        A {{*catchall}} route is added to the list of routes automatically in \r\n        case none of your routes match.\r\n    </p>\r\n    <p class=\"message\">\r\n        To generate URLs using routing, supply route values via the query string. example: <code>http://localhost:14230/?id=123</code>\r\n    </p>\r\n    <p><label>Matched Route</label>: {1}</p>\r\n    {5}\r\n    <div style=\"float: left;\">\r\n        <table border=\"1\" cellpadding=\"3\" cellspacing=\"0\" width=\"300\">\r\n            <caption>Route Data</caption>\r\n            <tr class=\"header\"><th>Key</th><th>Value</th></tr>\r\n            {0}\r\n        </table>\r\n    </div>\r\n    <div style=\"float: left; margin-left: 10px;\">\r\n        <table border=\"1\" cellpadding=\"3\" cellspacing=\"0\" width=\"300\">\r\n            <caption>Data Tokens</caption>\r\n            <tr class=\"header\"><th>Key</th><th>Value</th></tr>\r\n            {4}\r\n        </table>\r\n    </div>\r\n    <hr style=\"clear: both;\" />\r\n    <table border=\"1\" cellpadding=\"3\" cellspacing=\"0\">\r\n        <caption>All Routes</caption>\r\n        <tr class=\"header\">\r\n            <th>Matches Current Request</th>\r\n            <th>Url</th>\r\n            <th>Defaults</th>\r\n            <th>Constraints</th>\r\n            <th>DataTokens</th>\r\n        </tr>\r\n        {2}\r\n    </table>\r\n    <hr />\r\n    <h3>Current Request Info</h3>\r\n    <p>\r\n        AppRelativeCurrentExecutionFilePath is the portion of the request that Routing acts on.\r\n    </p>\r\n    <p><strong>AppRelativeCurrentExecutionFilePath</strong>: {3}</p>\r\n</div>\r\n</body>\r\n</html>";        string str4 = string.Empty;        //RouteData類包含所請求路由的相關值        RouteData routeData = this.RequestContext.RouteData;        //獲得路由的URL參數值和預設值的集合        RouteValueDictionary values = routeData.Values;        //擷取路由的對象        RouteBase base2 = routeData.Route;        string str5 = string.Empty;        using (RouteTable.Routes.GetReadLock())        {            foreach (RouteBase base3 in RouteTable.Routes)            {                //返回有關集合中與指定值匹配的路由的資訊,如果為空白,說明不匹配                bool flag = base3.GetRouteData(this.RequestContext.HttpContext) != null;                string str6 = string.Format("<span class=\"{0}\">{0}</span>", flag);                string url = "n/a";                string str8 = "n/a";                string str9 = "n/a";                string str10 = "n/a";                Route route2 = base3 as Route;                if (route2 != null)                {                    //如果路由不為空白,得到匹配的Url路由                    url = route2.Url;                    //得到預設的Url匹配規則資訊                    str8 = FormatRouteValueDictionary(route2.Defaults);                    //得到約束的Url匹配規則資訊                    str9 = FormatRouteValueDictionary(route2.Constraints);                    //得到命名空間的Url匹配規則資訊                    str10 = FormatRouteValueDictionary(route2.DataTokens);                }                str5 = str5 + string.Format("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>", new object[] { str6, url, str8, str9, str10 });            }        }        string str11 = "n/a";        string str12 = "";        //如果只被{@cacheall}捕獲時,提示不匹配        if (base2 is DebugRoute)        {            str11 = "<strong class=\"false\">NO MATCH!</strong>";        }        else        {            //匹配的路由資訊            foreach (string str2 in values.Keys)            {                str4 = str4 + string.Format("\t<tr><td>{0}</td><td>{1} </td></tr>", str2, values[str2]);            }            foreach (string str2 in routeData.DataTokens.Keys)            {                str12 = str12 + string.Format("\t<tr><td>{0}</td><td>{1} </td></tr>", str2, routeData.DataTokens[str2]);            }            Route route3 = base2 as Route;            if (route3 != null)            {                str11 = route3.Url;            }        }        context.Response.Write(string.Format(format, new object[] { str4, str11, str5, context.Request.AppRelativeCurrentExecutionFilePath, str12, str }));    }    public bool IsReusable    {        get        {            return true;        }    }    public RequestContext RequestContext    {        [CompilerGenerated]        get        {            return this.<RequestContext>k__BackingField;        }        [CompilerGenerated]        set        {            this.<RequestContext>k__BackingField = value;        }    }}

 通過ProcessRequest方法來處理請求,最後呈現在路由檢測的頁面上。

 首先從RequestContext.RouteData可以得到RouteData類,RouteData類包含所請求路由的相關值。從RouteData.Values擷取路由的URL參數值和預設值集合,在從RouteData.Route擷取路由的對象,在擷取有關集合中與指定值匹配的路由資訊.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.