在实际的项目中,会存在大量的自定义路由,URL很容易被错误的路由捕获,现在我们就实现一个这样的诊断工具,该工具通过实现一个自定义的IHttpModule来实现。
首先,我们创建CustomRouteHandler:
public class CustomRouteHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { if(HasQueryStringKey("routeInfo", requestContext.HttpContext.Request)) { OutputRouteDiagnostics(requestContext.RouteData, requestContext.HttpContext); } var handler = new CustomMvcHandler(requestContext); return handler; } private bool HasQueryStringKey(string keyToTest, HttpRequestBase request) { return Regex.IsMatch(request.Url.Query, string.Format(@"^\?{0}$", keyToTest)); } private void OutputRouteDiagnostics(RouteData routeData, HttpContextBase context) { var response = context.Response; response.Write( @"<style>body {font-family: Arial;} table th {background-color: #359; color: #fff;} </style> <h1>Route Data:</h1> <table border='1' cellspacing='0' cellpadding='3'> <tr><th>Key</th><th>Value</th></tr>"); foreach (var pair in routeData.Values) { response.Write(string.Format("<tr><td>{0}</td><td>{1}</td></tr>", pair.Key, pair.Value)); } response.Write( @"</table> <h1>Routes:</h1> <table border='1' cellspacing='0' cellpadding='3'> <tr><th></th><th>Route</th></tr>"); bool foundRouteUsed = false; foreach(Route r in RouteTable.Routes) { response.Write("<tr><td>"); bool matches = r.GetRouteData(context) != null; string backgroundColor = matches ? "#bfb" : "#fbb"; if(matches && !foundRouteUsed) { response.Write("»"); foundRouteUsed = true; } response.Write(string.Format( "</td><td style='font-family: Courier New; background-color:{0}'>{1}</td></tr>", backgroundColor, r.Url)); } response.End(); } }
CustomRouteHandler中使用到了一个CustomMvcHandler,如下:
public class CustomMvcHandler : MvcHandler { public CustomMvcHandler(RequestContext requestContext) : base(requestContext) { } protected override void ProcessRequest(HttpContext httpContext) { try { base.ProcessRequest(httpContext); } catch (Exception exc) { throw new ApplicationException("RouteUsed:" + RequestContext.RouteData.Route.GetVirtualPath( RequestContext, RequestContext.RouteData.Values), exc); } } }
其次,我们需要在MapRoute的时候指定CustomRouteHandler,如下:
routes.MapRoute( "Default", // Route name "Home/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ).RouteHandler = new CustomRouteHandler();
最终的结果,如果我们想要看当前URL的路由信息,则输入URL如:http://localhost:12205/Home?routeInfo,会显式如下: