ASP.NET MVC Url.Action adds current route values to generated url

前端 未结 7 1213
孤独总比滥情好
孤独总比滥情好 2020-12-07 20:26

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

7条回答
  •  情深已故
    2020-12-07 20:52

    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;
    }
    

提交回复
热议问题