仅从路径数据生成URL

时间:2011-12-30 14:17:10

标签: asp.net-mvc asp.net-mvc-3 routes

我正在尝试在ASP.NET MVC中做一些简单的事情:

RouteValuesDictionary routeValues = GetMyRouteData();
var url = new UrlHelper(Html.ViewContext.RequestContext);
return url.RouteUrl(routeValues);

问题在于,无论我做什么,网址都包含来自当前请求上下文的路由数据。我想仅根据GetMyRouteData()的路由值生成一个URL。

由于

3 个答案:

答案 0 :(得分:7)

  

问题是无论我做什么,网址都包含路由数据   来自当前的请求上下文

这是设计的。您必须显式设置原始请求中存在的路由值,并且您不希望在生成的URL中为null:

    var routeValues = GetMyRouteData();
    // remove values that you want to exclude from the resulting url
    // by setting their values to null
    routeValues["id"] = null;
    var url = new UrlHelper(Html.ViewContext.RequestContext);
    return url.RouteUrl(routeValues);

答案 1 :(得分:2)

这不是ASP.NET MVC特有的,而是由于ASP.NET Routing的路由解析。它的入口点是RouteCollection.GetVirtualPath,它有两个签名。

第一个需要RequestContextRouteValueDictionary。这用于默认路由解析,它依赖于模式匹配来查找路由。路径搜索包含来自RequestContext以及RouteValueDictionary的所有令牌;换句话说,两组路线令牌被组合以形成路线搜索的基础。存在一种特殊情况,即RouteValueDictionary中的空参数从搜索中删除该参数。但是,如果此类空值参数在RequestContext中具有值,则该值仍将作为查询字符串值显示在生成的URL中。

另一个签名还接受路线名称。这有点奇怪,因为它改变了路由解析和查询字符串创建。显然,使用名称解析找到路由。如果找到了命名路由,则只有路由URL模式中指定的参数的标记才会出现在生成的URL中。

为什么会这样?这是ASP.NET MVC对Ruby on Rails参数处理约定的解释。

因此,默认路由解析和“后备”令牌解析混合。如果您不希望令牌回退到RequestContext,(并且您仍然希望使用ASP.NET路由),则必须使用命名路由解析。

答案 2 :(得分:0)

这可能有助于澄清。使用来源,卢克!

RouteUrl助手调用此静态方法来生成URL:

public static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
        if (routeCollection == null) {
            throw new ArgumentNullException("routeCollection");
        }

        if (requestContext == null) {
            throw new ArgumentNullException("requestContext");
        }

        RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);

        VirtualPathData vpd = routeCollection.GetVirtualPathForArea(requestContext, routeName, mergedRouteValues);
        if (vpd == null) {
            return null;
        }

        string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath);
        return modifiedUrl;
}

注意这一行:

RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);

这是合并在封面下的当前requestcontext值。因此,您可以创建自己的帮助程序,只需调用此静态方法并传递空集合,以避免合并当前路由上下文值。尝试并调试到MVC代码中,您应该能够看到所需的值核武器。