2016-07-08 3 views
2

확장 메서드를 사용하여 메뉴의 활성 링크에서 CSS 클래스를 유지 관리하고 있습니다.ActionLink Extension 메서드의 htmlAttributes

그러나 htmlAttributes 및 개체 값이 오류를 일으키는 문제가 있습니다.

내 면도기 페이지에 아래 내용이 있지만 어떻게 htmlAttributes를 구문 분석 할 것인지 이해할 수 없습니다. Html 헬퍼보고에서

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

방법은 htmlAttributes의 유형으로 IDictionary<object, string>이 있어야합니다. 새로운 { @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"입니다. 당신의 의도는 속성 플러스 (조건에 따라) 클래스 이름을 추가 할 경우에는 다음 경로 값과 HTML 속성을 모두 정의 할 수 있도록

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

완전한 방법을 사용할 수 있으며, 조건부 "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 routeValues와 내장 ActionLink() 방법에 따라 IDictionary<String, Object>) htmlAttributes을 받아 다른 오버로드를 포함하여 고려해야하고 다양한 오버로드가 인접 해로 넘어 방식을 볼 source code을 검사 할 수 있습니다 r 과부하.

+0

훌륭합니다. 확장 메소드가 완전하지 않아서 고맙습니다. 코드를 가지고 놀고 있었고 HtmlHelper가 어떻게 그것을 달성했는지 알아 내려고했습니다. – PurpleSmurph

+0

object 매개 변수에 다른 클래스 이름을 전달할 가능성이있는 경우'if (attributes.Contains ("class")'를 검사하고 추가 "currentMenu"클래스를 기존 클래스 이름에 추가해야합니다. 아침에 완전한 코드를 추가해 다양한 오버로드를 만드는 방법을 설명하는 데 도움이되는 소스 코드에 대한 링크를 추가 할 것입니다. –

+0

그게 어디에서 왔는지 보니 정말 좋을 텐데, 대단히 감사합니다! – PurpleSmurph