Hi,
In this article I’ll talk about ASP.NET MVC Routes and Regular Expression. I based my article from the Fredrik Kalseth’s Blog about Defining Routes using Regular Expressions in ASP.NET MVC.
Fredrik provides a Custom Implementation of Route in order to be able to use Regular Expression Patterns with MVC Routing.
However we are not able to use that with the MapRoute Extension Method of RouteCollection.
So Here is a Custom Implementation of the MapRoute Extension Method which takes advantage of RegexRoute Implementation made by Fredrik.
RegexRoute :
public class RegexRoute : Route
{
#region Private Fields
private readonly Regex _urlRegex;
#endregion
#region Constructors
public RegexRoute(Regex urlPattern, IRouteHandler routeHandler)
: this(urlPattern, null, routeHandler)
{
}
public RegexRoute(Regex urlPattern, RouteValueDictionary defaults, IRouteHandler routeHandler)
: base(null, defaults, routeHandler)
{
_urlRegex = urlPattern;
}
#endregion
#region Public Overrides Methods
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var requestUrl = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
var match = _urlRegex.Match(requestUrl);
RouteData data = null;
if (match.Success)
{
data = new RouteData(this, RouteHandler);
// add defaults first
if (null != Defaults)
{
foreach (var def in Defaults)
{
data.Values[def.Key] = def.Value;
}
}
// iterate matching groups
for (var i = 1; i < match.Groups.Count; i++)
{
var group = match.Groups[i];
if (!group.Success) continue;
var key = _urlRegex.GroupNameFromNumber(i);
if (!String.IsNullOrEmpty(key) && !Char.IsNumber(key, 0))
{
data.Values[key] = group.Value;
}
}
}
return data;
}
#endregion
}
RegexRouteCollectionExtensions
public static class RegexRouteCollectionExtensions
{
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern)
{
return routes.MapRoute(name, urlPattern, null, null);
}
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern, object defaults)
{
return routes.MapRoute(name, urlPattern, defaults, null);
}
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern, string[] namespaces)
{
return routes.MapRoute(name, urlPattern, null, null, namespaces);
}
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern, object defaults, object constraints)
{
return routes.MapRoute(name, urlPattern, defaults, constraints, null);
}
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern, object defaults, string[] namespaces)
{
return routes.MapRoute(name, urlPattern, defaults, null, namespaces);
}
public static Route MapRoute(this RouteCollection routes, string name, Regex urlPattern, object defaults, object constraints, string[] namespaces)
{
if (routes == null)
{
throw new ArgumentNullException("routes");
}
if (urlPattern == null)
{
throw new ArgumentNullException("urlPattern");
}
var route2 = new RegexRoute(urlPattern, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(defaults),
Constraints = new RouteValueDictionary(constraints)
};
var item = route2;
if ((namespaces != null) && (namespaces.Length > 0))
{
item.DataTokens = new RouteValueDictionary();
item.DataTokens["Namespaces"] = namespaces;
}
routes.Add(name, item);
return item;
}
}
Sample Usage (Global.asax)
public class Global : HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("Books", new Regex(@"^Books/((?<ssn>[\d]{3}(-?)[\d]{2}\1[\d]{4})|(?<query>.+)?)$", RegexOptions.Compiled),
new { controller = "Books", action = "Index" });
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
Hope this help’s!
Views(3705)

