Include and Exclude Constraints in ASP.NET MVC
Otherwise known as a white list or black list for route tokens, this simple IRouteConstraint is coming in handy and I thought i would share:
- public enum ListConstraintType {
- Exclude,
- Include
- }
- public class ListConstraint : IRouteConstraint {
- public ListConstraintType ListType { get; set; }
- public IList<string> List { get; set; }
- public ListConstraint() : this(ListConstraintType.Include, new string[] { }) { }
- public ListConstraint(params string[] list) : this(ListConstraintType.Include, list) { }
- public ListConstraint(ListConstraintType listType, params string[] list) {
- if (list == null) throw new ArgumentNullException("list");
- this.ListType = listType;
- this.List = new List<string>(list);
- }
- public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
- if (string.IsNullOrEmpty(parameterName)) throw new ArgumentNullException("parameterName");
- if (values == null) throw new ArgumentNullException("values");
- string value = values[parameterName.ToLower()] as string;
- bool found = this.List.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase));
- return this.ListType == ListConstraintType.Include ? found : !found;
- }
- }
You can then use the ListConstraint like this:
- public static void RegisterRoutes(RouteCollection routes) {
- routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
- routes.IgnoreRoute("content/{*pathInfo}");
- routes.IgnoreRoute("favicon.ico");
- routes.MapRoute(
- "UserShortcuts",
- "{action}/{id}",
- new { controller = "user", id = "" },
- new { action = new ListConstraint(ListConstraintType.Include, "signin", "signout") }
- );
- routes.MapRoute(
- "HomeShortcuts",
- "{action}",
- new { controller = "home" },
- new { action = new ListConstraint("sitemap", "contact") } //default Include
- );
- routes.MapRoute(
- "Default",
- "{controller}/{action}/{id}",
- new { controller = "home", action = "index", id = "" },
- new { id = new ListConstraint(ListConstraintType.Exclude, "123") }
- );
- }
- protected void Application_Start() {
- RegisterRoutes(RouteTable.Routes);
- }
Which then allows only those included constraints to use the UserShortcuts route:
Or prevents the id of 123 from being used on the Default route:
Hope folks find this useful,
Jason Conway