转载:http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/
Lowercase Route URL's in ASP.NET MVC
For anybody interesting in having ruby on rails style routes; or follow a lowercase URL pattern (mysite.com/member/profile/goneale) which most web 2.0 sites seem to be following, check out the below code cited and enhanced from this article (http://www.makiwa.com/index.php/2008/05/31/lowercase-mvc-route-urls/).
Firstly you will need a RouteExtensions.cs
file, or named anything you like with the following (compatible as at ASP.NET MVC RC1):
- using System;
- using System.Web.Mvc;
- using System.Web.Routing;
- namespace MyMvcApplication.App.Helpers
- {
- public class LowercaseRoute : System.Web.Routing.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)
- {
- VirtualPathData path = base.GetVirtualPath(requestContext, values);
- if (path != null)
- path.VirtualPath = path.VirtualPath.ToLowerInvariant();
- return path;
- }
- }
- public static class RouteCollectionExtensions
- {
- public static void MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults)
- {
- routes.MapRouteLowercase(name, url, defaults, null);
- }
- public static void MapRouteLowercase(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);
- }
- }
- }
Then a using reference in your Global.asax.cs
file to the above class, and you’re all set to create a lowercase route.
You can see a below example of a lowercase route and anytime this route is called your URL will be lowercased.
- routes.MapRouteLowercase(
- "Default", // Route name
- "{controller}/{action}/{id}", // URL with parameters
- new {controller = "Home", action = "index", id = ""} // Parameter defaults
- );
and optionally if you are interested in converting any incoming URL’s to lowercase (manually typed by the user or called links) you can use this in your Application_BeginRequest()
method (Remember, this is not needed for lowercase routes themselves, the code above will handle that):
- protected void Application_BeginRequest(Object sender, EventArgs e)
- {
- // If upper case letters are found in the URL, redirect to lower case URL.
- // Was receiving undesirable results here as my QueryString was also being converted to lowercase.
- // You may want this, but I did not.
- //if (Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), @"[A-Z]") == true)
- //{
- // string LowercaseURL = HttpContext.Current.Request.Url.ToString().ToLower();
- // Response.Clear();
- // Response.Status = "301 Moved Permanently";
- // Response.AddHeader("Location", LowercaseURL);
- // Response.End();
- //}
- // If upper case letters are found in the URL, redirect to lower case URL (keep querystring the same).
- string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
- if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
- {
- lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query;
- Response.Clear();
- Response.Status = "301 Moved Permanently";
- Response.AddHeader("Location", lowercaseURL);
- Response.End();
- }
- }