MVC TIP7:自定义IHttpModule、IRouteHandler实现路由调试

在实际的项目中,会存在大量的自定义路由,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("&raquo;");

                    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,会显式如下:

image

你可能感兴趣的:(handler)