Tuesday, October 30, 2012

Lowercase route example in ASP.NET MVC

I like default URL routing behaviour of ASP.NET MVC, but sometimes you want something special.

Let's say we want Lower Case URLs in our Web site. Here's an example of Global.asax:
 public class MvcApplication : System.Web.HttpApplication  
   {  
     public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
     {  
       filters.Add(new HandleErrorAttribute());  
     }  
     public static void RegisterRoutes(RouteCollection routes)  
     {  
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
       routes.MapLowercaseRoute(  
         "Default", // Route name  
         "{controller}/{action}/{id}", // URL with parameters  
         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults  
       );  
     }  
     protected void Application_Start()  
     {  
       AreaRegistration.RegisterAllAreas();  
       RegisterGlobalFilters(GlobalFilters.Filters);  
       RegisterRoutes(RouteTable.Routes);  
     }  
   }  

MapLowercaseRoute is an extension method for RouteCollection class. It's looks like:
 public static class RoutesEx  
   {  
     public static void MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults)  
     {  
       routes.MapLowercaseRoute(name, url, defaults, null);  
     }  
     public static void MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults,  
                      object constraints)  
     {  
       if (routes == null)  
         throw new ArgumentNullException("routes");  
       if (url == null)  
         throw new ArgumentNullException("url");  
       var route = new LowercaseRoute(url, new MvcRouteHandler())  
       {  
         Defaults = new RouteValueDictionary(defaults),  
         Constraints = new RouteValueDictionary(constraints)  
       };  
       if (String.IsNullOrEmpty(name))  
         routes.Add(route);  
       else  
         routes.Add(name, route);  
     }      
   }  

The key point is LowercaseRoute class that does lowercasing:
 public class LowercaseRoute : Route  
   {  
     public LowercaseRoute(string url, IRouteHandler routeHandler)  
       : base(url, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)  
       : base(url, defaults, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)  
       : base(url, defaults, constraints, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { }  
     public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)  
     {  
       var path = base.GetVirtualPath(requestContext, values);  
       if (path != null)  
         path.VirtualPath = path.VirtualPath.ToLowerInvariant();  
       return path;  
     }  
   }  

As you see, it's very easy to make some elaborations to default ASP.NET MVC routing machinery.

No comments:

Post a Comment