这篇教程要演示如何创建自定义路由约束。自定义路由约束能够使路由只有达到某些自定义条件时才会匹配。
在这篇教程里,我们创建一个 Localhost 路由约束。 它只匹配从本地计算机发出的请求。通过Internet发送的远程请求不被匹配。
要实现自定义路由约束就要实现 IRouteConstraint接口。这个接口极其简单,就描述了一个简单方法:
bool Match( HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection )
方法返回一个布尔值。返回false的话,被约束的路由不匹配浏览器请求。
Localhost约束见代码 1.
代码1 – LocalhostConstraint.cs
using System.Web; using System.Web.Routing; namespace MvcApplication1.Constraints { public class LocalhostConstraint : IRouteConstraint { public bool Match ( HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection ) { return httpContext.Request.IsLocal; } } }
代码1的约束利用了由HttpRequest类暴露的 IsLocal属性。当请求的IP地址是127.0.0.1或者与服务器IP地址一样时,这个属性就返回true。
使用在Global.asax文件中定义的自定义约束。代码2中的 Global.asax 文件使用了 Localhost 约束来防止来自Admin页的任何请求,除非它们是从本地服务器发出的。例如,从远程服务器发送 /Admin/DeleteAll 请求将会失败。
代码2 – Global.asax
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using MvcApplication1.Constraints; namespace MvcApplication1 { public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute("Admin", "Admin/{action}", new { controller = "Admin" }, new { isLocal = new LocalhostConstraint() }); //routes.MapRoute( // "Default", // Route name // "{controller}/{action}/{id}", // URL with parameters // new { controller = "Home", action = "Index", id = "" } // Parameter defaults //); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes); } } }
Localhost 约束被用在Admin路由的定义上。这个路由不会被远程浏览器请求所匹配。然而,其他定义在Global.asax中的路由有可能匹配相同的请求。重点理解的是,约束只防止特定的一个路由匹配请求而不是Global.asax文件中定义的所有路由。
注意 Default 路由在代码2中已经被注释掉了。如果你包括了 Default 路由,那么 Default 路由会匹配Admin控制器的的请求。在这种情况下,远程用户仍然可以调用Admin控制器的action,即使它们的请求不会匹配Admin路由。