Have you ever needed to rewrite/redirect old URLs that have very similar pattern as your new, modern URLs, but want to do it with simple, maintainable code?
In the following URL you very specifically can see an ID
-value and a potential Category
-value.
http://test.com/products/details.aspx?id=123&category=tea-cups
So you probably want to use Regex and point out named groups in above URL.
^(?:.*)\/?products\/details\.aspx\?id=(?<id>[\d]*)(&category=(?<category>[^&]*))?
Then you want to get those named values into a RouteValueDictionary
, with above named Key
s, like <id>
and <category>
with the Regex-matched Value
s in the URL. You can then, for example, send it to a UrlHelper
. This is what the following method does:
public static RouteValueDictionary GetRegexRouteValues(string url, string urlPattern)
{
if (url == null)
{
throw new ArgumentNullException("url");
}
if (urlPattern == null)
{
throw new ArgumentNullException("urlPattern");
}
var regex = new Regex(urlPattern);
var match = regex.Match(url);
if (!match.Success)
{
return null;
}
var namedGroupNames = regex.GetGroupNames().Where(x => x != null && !Regex.IsMatch(x, @"^[0-9]+$"));
var groups = (from groupName in namedGroupNames
let groupItem = match.Groups[groupName]
where groupItem != null
select new KeyValuePair<string, string>(groupName, groupItem.Value)).ToList();
var routeValues = new RouteValueDictionary();
groups.ForEach(x => routeValues.Add(x.Key, x.Value));
return routeValues;
}
Now you can write code that is more easy to read and maintain to redirect specific URLs:
private static void RedirectProductDetails(string requestUrl) {
string urlRegex = @"^(?:.*)\/?products\/details\.aspx\?id=(?<id>[\d]*)(&category=(?<category>[^&]*))?";
var routeValues = GetRegexRouteValues(requestUrl, urlRegex);
routeValues["controller"] = "Products";
routeValues["action"] = "Details";
return this.Url.RouteUrl(routeValues);
}