I have seen this question a couple of times here in SO but none of them with any acceptable answer:
ASP.NET MVC @Url.Action includes current route data
ASP.NET M
My application explicitly sets route values and does not want a magical value from the current request. I want to be in full control.
I have made an extension which coexists with my route library collection. Hence the single RouteValueDictionary param. (See my Route library comment at the bottom)
Here I remove any routevalues from the request prior to generating a url.
(note: for the array.contains ignorecase part, see: How can I make Array.Contains case-insensitive on a string array?)
public static string Action(this UrlHelper helper,
RouteValueDictionary routeValues)
{
RemoveRoutes(helper.RequestContext.RouteData.Values);
string url = helper.Action(routeValues["Action"].ToString(), routeValues);
return url;
}
public static void RemoveRoutes(RouteValueDictionary currentRouteData)
{
List keyList = new List(currentRouteData.Keys);
string[] ignore = new[] { "Area", "Controller", "Action" };
foreach (string key in keyList)
{
if (!ignore.Contains(key, StringComparer.CurrentCultureIgnoreCase))
currentRouteData.Remove(key);
}
}
I have Form and ActionLink extension methods that uses the RemoveRoutes method. No helper in my mvc library uses a method that is not an extension method i have created. Thereby, all routedata is cleaned up before generating urls.
For reference I use AttributeRouting. Here is an example of one route from my route library.
public static RouteValueDictionary DisplayNews(int newsId)
{
RouteValueDictionary route = new RouteValueDictionary();
route["Area"] = _area;
route["Controller"] = _controller;
route["Action"] = "DisplayNews";
route["newsId"] = newsId;
return route;
}