2016-07-08 30 views
2

我正在使用擴展方法在菜單上的活動鏈接上維護一個css類。ActionAction中的htmlAttributes擴展方法MVC5

但是我有一個問題,htmlAttributes和對象值導致錯誤。

我在我的剃刀頁面下面,但我不明白我是如何解析htmlAttributes。

@Html.MenuLink("Summary", "Summary", "Graphs", null, new { @class = "dropdown-toggle caret", data_target = "#", data_toggle = "dropdown" }) 

從看的HtmlHelper的方法應該有IDictionary<object, string>作爲htmlAttributes類型。新的{ @class = "dropdown-toggle caret", data_target = "#", data_toggle = "dropdown" }語法對字典不典型,所以這是正確的嗎?

很顯然,我做錯了什麼,因爲它的返回下面的錯誤:

Argument 6: cannot convert from '<anonymous type: string class, string data_target, string data_toggle>' to 'System.Collections.Generic.IDictionary<object, string>' 

擴展方法,我試圖讓下面的工作:

public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string text, string action, string controller, RouteValueDictionary routeValues, IDictionary<object, string> htmlAttributes) 
     { 
      var routeData = htmlHelper.ViewContext.RouteData.Values; 

      var currentController = routeData["controller"]; 
      var currentAction = routeData["action"]; 

      if (string.Equals(action, currentAction as string, StringComparison.OrdinalIgnoreCase) && 
       string.Equals(controller, currentController as string, StringComparison.OrdinalIgnoreCase)) 
      { 
       return htmlHelper.ActionLink(text, action, controller, null, new { @class = "currentMenu" }); 
      } 

      return htmlHelper.ActionLink(text, action, controller); 
     } 

回答

4

變化從IDictionary<object, string> htmlAttributesobject htmlAttributes參數因爲你將屬性作爲對象傳遞。

然後可以轉換爲使用

var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 

然而,任何地方在你的擴展方法你曾經使用屬性的對象。根據當前的控制器和操作名稱,您的所有生成都是class = "currentMenu"。如果你的目的是添加的屬性加類名(視情況),你就可以使用

attributes.Add("class", "currentMenu"); 

你完整的方法,以允許定義兩種路線的價值觀和HTML屬性,並有條件地包括"currentMenu"類名稱應爲

public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string text, string action, string controller, object routeValues, object htmlAttributes) 
{ 
    var routeData = htmlHelper.ViewContext.RouteData.Values; 
    string currentController = (string)routeData["controller"]; 
    string currentAction = (string)routeData["action"]; 
    if (string.Equals(action, currentAction, StringComparison.OrdinalIgnoreCase) && string.Equals(controller, currentController, StringComparison.OrdinalIgnoreCase)) 
    { 
     if (htmlAttributes == null) 
     { 
      return htmlHelper.ActionLink(text, action, controller, routeValues, new { @class = "currentMenu" }); 
     } 
     else 
     { 
      // convert object to RouteValueDictionary 
      var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
      if (attributes.ContainsKey("class")) 
      { 
       // append the class name 
       attributes["class"] = string.Format("{0} currentMenu", attributes["class"]); 
      } 
      else 
      { 
       // add the class name 
       attributes.Add("class", "currentMenu"); 
      } 
      return htmlHelper.ActionLink(text, action, controller, new RouteValueDictionary(routeValues), attributes); 
     } 
    } 
    return htmlHelper.ActionLink(text, action, controller, routeValues, htmlAttributes); 
} 

附註:您還應該考慮包括其他重載接受RouteValueDictionary routeValuesIDictionary<String, Object>) htmlAttributes爲每內置ActionLink()方法,你可以檢查source code看到各種重載如何告吹的行吟詩人r重載。

+0

輝煌 - 謝謝你,是的擴展方法不完整,我正在玩弄代碼,並試圖找出HtmlHelper如何實現它。 – PurpleSmurph

+0

如果你可能在對象參數中傳遞了其他類名,那麼你還需要檢查'if(attributes.Contains(「class」)''並將額外的「currentMenu」類添加到現有的類名中。但我會在早上添加完整的代碼,包括鏈接到源代碼,這將有助於解釋如何創建各種過載。 –

+0

這將是很高興看到它來自哪裏,非常感謝! – PurpleSmurph