T4MVC SEO的链接

时间:2009-12-11 12:22:59

标签: asp.net-mvc seo t4mvc

我正在尝试将我们的链接切换到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),同时在URL中保留fooKey和barKey。

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

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

由于barKey和fooKey不是详细信息操作签名的一部分,因此URL中不再显示它们。

有没有办法绕过这个而不必将这些参数添加到动作签名中?

3 个答案:

答案 0 :(得分:9)

T4MVC论坛(this thread)也出现了类似的情况。我想我会继续在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;
}

如果你能试一试并告诉我这对你有什么用,那就太好了。

感谢, 大卫

答案 1 :(得分: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);
    }

答案 2 :(得分:-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);
    }