【问题标题】:T4MVC Links for SEO用于 SEO 的 T4MVC 链接
【发布时间】:2010-12-25 15:44:27
【问题描述】:

我正在尝试将我们的链接切换到 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 中不再可见。

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

【问题讨论】:

  • 你的路由是怎么配置的?
  • 相关路由是这样配置的:routes.Add(new LowercaseRoute("go/{fooKey}/{barKey}/{id}", new RouteValueDictionary(new {controller = "Bar", action = "Details"}), new RouteValueDictionary(new {id = @"\d+"}), new MvcRouteHandler()));从这里开始的小写路线 - coderjournal.com/2008/03/force-mvc-route-url-lowercase
  • (对不起,缩进很糟糕)

标签: asp.net-mvc seo t4mvc


【解决方案1】:

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

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

谢谢, 大卫

【讨论】:

  • 效果很好,而且是一个非常优雅的解决方案。谢谢,大卫!
【解决方案2】:

查看 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);
    }

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 你应该使用 cmets 来回答,而不是新的答案
    • @Omer Rauchwerger :如果您根据 jfar 的回答使用此代码解决了问题,那么您应该接受 jfar 的回答 - 发布您的工作代码的最佳位置是对 jfar 的回答进行编辑,不在单独的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 2014-02-15
    • 2012-05-18
    • 2022-08-10
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多