Your methods like RedirectToActionPermanent, Url.Action, etc. all take an optional object for route values.
This works most of the time.
However, if you pass in an actual ``RouteValueDictonary' to the methods they do not work. The standard MVC library code that takes this kind of value does work.
You could create overloads that accept the RouteValueDictionary and act appropriately:
public static string Action<TController>(this UrlHelper url, Expression<Action<TController>> action, RouteValueDictionary routeValues) where TController : Controller
{
RouteInformation routeInformation = FromExpression<TController>(action, routeValues);
return url.Action(routeInformation.ActionName, routeInformation.ControllerName, routeInformation.RouteValueDictionary);
}
public static string Action<TController>(this UrlHelper url, Expression<Func<TController, Task>> action, RouteValueDictionary routeValues) where TController : Controller
{
RouteInformation routeInformation = FromExpression<TController>(action, routeValues);
return url.Action(routeInformation.ActionName, routeInformation.ControllerName, routeInformation.RouteValueDictionary);
}
public static RouteInformation FromExpression<TController>(LambdaExpression action, RouteValueDictionary routeValueDictionary)
where TController : Controller
{
string actionName = action.GetActionName();
var controllerType = typeof(TController);
string controllerName = controllerType.GetControllerName();
routeValueDictionary.ProcessParameters(action);
routeValueDictionary.ProcessArea(controllerType);
var routeInformation = new RouteInformation(actionName, controllerName, routeValueDictionary);
return routeInformation;
}
That would be a lot of overloads.
Or you could create a shared routine that creates the initial route value dictionary correctly, something like
private RouteValueDictionary GetDictionaryFromObject( object routeValues){
if (routeValues is RouteValueDictionary)
return (RouteValueDictionary)routeValues;
return new RouteValueDictionary(routeValues);