3

我正在尝试将我们的链接切换到T4MVC,但我遇到了一个不属于动作签名的参数的小问题。我们的路线是这样的:

http://www.mydomain.com/{fooKey}/{barKey}/{barID}

==> 导致BarController.Details(barID)

fooKey 和 barKey 仅出于 SEO 目的添加到链接中。(因为 bar 是 foo 的子实体,我们希望在 URL 中表示该层次结构)

到目前为止,我们会使用

<% =Html.ActionLink(bar.Name, "Details", "Bar", new {barID = bar.ID, fooKey = bar.Foo.Key, barKey = bar.Key}, null)%>

这将引导我们到 BarController.Details(barID),同时将 fooKey 和 barKey 保留在 URL 中。

现在我们从 T4MVC 开始,我们尝试将其更改为

<% =Html.ActionLink(bar.Name, MVC.Bar.Details(bar.ID), null)%>

由于 barKey 和 fooKey 不是 Details 操作签名的一部分,因此它们不再在 URL 中可见。

有没有办法解决这个问题而不必将这些参数添加到动作签名中?

4

3 回答 3

9

T4MVC 论坛(此线程)上也出现了类似的情况。我想我会继续在 T4MVC 中添加对它的支持。

实际上,我只是想到了一个有趣的方法来解决这个问题。添加重载以传递额外参数的问题在于,您需要向所有其他采用 ActionResult 的 T4MVC 扩展方法添加类似的重载,这可能会变得混乱。

取而代之的是,我们可以使用一种流畅的方法来轻松地在任何地方使用它。这个想法是你会写:

<%= Html.ActionLink(
    bar.Name,
    MVC.Bar.Details(bar.ID)
        .AddRouteValues(new {fooKey = bar.Foo.Key, barKey = bar.Key}))%>

或者,如果您只需要添加一个值:

<%= Html.ActionLink(
    bar.Name,
    MVC.Bar.Details(bar.ID)
        .AddRouteValue("fooKey", bar.Foo.Key))%>

下面是 AddRouteValues 的实现方式:

public static ActionResult AddRouteValues(this ActionResult result, object routeValues) {
    return result.AddRouteValues(new RouteValueDictionary(routeValues));
}

public static ActionResult AddRouteValues(this ActionResult result, RouteValueDictionary routeValues) {
    RouteValueDictionary currentRouteValues = result.GetRouteValueDictionary();

    // Add all the extra values
    foreach (var pair in routeValues) {
        currentRouteValues.Add(pair.Key, pair.Value);
    }

    return result;
}

public static ActionResult AddRouteValue(this ActionResult result, string name, object value) {
    RouteValueDictionary routeValues = result.GetRouteValueDictionary();
    routeValues.Add(name, value);
    return result;
}

如果你能试一试,让我知道它对你有用,那就太好了。

谢谢,大卫

于 2009-12-13T19:01:22.353 回答
1

查看 T4MVC.cs 中生成的代码。有采用 ActionLink 的 html 帮助程序扩展。您将不得不编写一个重载,该重载采用另一组路由值并将它们与 ActionResult.GetRouteValueDictionary() 组合。

    public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, ActionResult result, IDictionary<string, object> htmlAttributes) {
        return htmlHelper.RouteLink(linkText, result.GetRouteValueDictionary(), htmlAttributes);
    }
于 2009-12-11T14:51:57.393 回答
-1

谢谢jfar!

这是我使用的代码,以防万一有人需要。它可以使用重构工作,但它可以工作

public static MvcHtmlString ActionLink<T>(this HtmlHelper<T> htmlHelper, string linkText, ActionResult result,
                                              object extraRouteValues, object htmlAttributes)
    {
        RouteValueDictionary completeRouteValues = result.GetRouteValueDictionary();
        RouteValueDictionary extraRouteValueDictionary = new RouteValueDictionary(extraRouteValues);
        foreach (KeyValuePair<string, object> foo in extraRouteValueDictionary)
        {
            completeRouteValues.Add(foo.Key, foo.Value);
        }

        Dictionary<string, object> htmlAttributesDictionary = htmlAttributes != null ? htmlAttributes.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)) : null;

        return htmlHelper.RouteLink(linkText, completeRouteValues, htmlAttributesDictionary);
    }
于 2009-12-12T17:34:20.117 回答