2009-12-11 5 views
3

Я пытаюсь переключить наши ссылки на T4MVC, и у меня небольшая проблема с параметрами, которые не являются частью сигнатуры действия. У нас есть маршрут, который проходит что-то вроде этого:T4MVC Ссылки для SEO

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

==> приводит к BarController.Details (barID).

fooKey и barKey добавляются только к ссылкам для целей SEO. (поскольку бар является дочерним субъектом обув, и мы хотим, чтобы представить эту иерархию в 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)%> 

С Барки и fooKey не являются частью подписи детали действия, они больше не будут видны в URL.

Есть ли способ обойти это без необходимости добавлять эти параметры к сигнатуре действия?

+0

Как настроено маршрутизация? – PanJanek

+0

Соответствующий маршрут сконфигурирован следующим образом: routes.Add (новый или нижний регистр) (44), новый RouteValueDictionary (new {controller = "Bar", action = "Подробнее "}), новый RouteValueDictionary (новый {id = @" \ d + "}), новый MvcRouteHandler())); Нижняя регистрRoute отсюда - http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ –

+0

(Извините за страшный отступ) –

ответ

9

Похожие вещи подвигнулся на T4MVC форуме (this thread). Думаю, я продолжу и добавлю поддержку в T4MVC.

На самом деле, я просто подумал об интересном способе решить эту проблему. Проблема с добавлением перегрузки для передачи дополнительных аргументов заключается в том, что вам нужно будет добавить похожие перегрузки ко всем другим методам расширения T4MVC, которые принимают ActionResult, которые могут стать беспорядочными.

Вместо этого мы можем использовать свободный подход, чтобы сделать его доступным везде с минимальными усилиями. Идея заключается в том, что вы будете писать:

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

Было бы отлично, если бы вы могли дать это попробовать и сообщить мне, как это работает для вас.

спасибо, David

+0

Прекрасно работает и очень элегантное решение. Спасибо, Дэвид! –

1

Посмотрите в сгенерированном коде внутри T4MVC.cs. Существуют расширения html-помощников, которые используют ActionLink. Вам придется написать перегрузку, которая берет другой набор значений маршрута и объединяет их с ActionResult.GetRouteValueDictionary().

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, ActionResult result, IDictionary<string, object> htmlAttributes) { 
     return htmlHelper.RouteLink(linkText, result.GetRouteValueDictionary(), htmlAttributes); 
    } 
-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); 
    } 
+0

вам следует ответить, используя комментарии, а не новый ответ – awrigley

+0

@ Omer Rauchwerger: Если вы решили проблему с помощью этого кода, основываясь на ответе jfar, тогда вы должны принять ответ jfar, и лучшее место для публикации вашего рабочего кода является редактированием ответа jfar, а не отдельным ответом. –