2009-12-11 191 views
3

我想把我們的鏈接切換到T4MVC,而且我的參數不屬於某個動作的簽名。我們有一個是這樣的路線:T4MVC搜索引擎優化的鏈接

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

==>導致BarController.Details (barID)

fooKey和barKey只添加到鏈接爲SEO的目的。 (因爲酒吧是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中可見。

有沒有辦法解決這個問題,而不必將這些參數添加到動作簽名中?

+0

你的路由如何配置? – PanJanek

+0

相關路線配置如下: routes.Add(新的LowercaseRoute(「go/{fooKey}/{barKey}/{id}」, new RouteValueDictionary(new {controller =「Bar」,action =「Details 「}), new RouteValueDictionary(new {id = @」\ d +「}),new MvcRouteHandler())); LowercaseRoute from here - http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ –

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

這將是如果你可以試試這個,並且讓我知道那對你有用,那就太好了。

謝謝, 大衛

+0

工程很好,而且是一個非常優雅的解決方案。謝謝,大衛! –

1

查看T4MVC.cs中生成的代碼。有一些採用ActionLink的html helper擴展。你將不得不編寫一個重載,它接受另一組路由值並將它們與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 @Omer Rauchwerger:如果你使用這段代碼解決了你的問題,那麼你應該接受jfar的答案 - 並且發佈你的工作代碼的最佳地方是作爲jfar答案的編輯,而不是單獨的答案。 –