2009-11-10 7 views
2

나는 다음과 같이 주어진 강력한 형식의 컨트롤러/액션 메뉴 항목에서 쓰는 내 응용 프로그램에 대한 도우미 쓰고 :이 과정의 일환으로, 신청하고자비교 두 RouteValueDictionary 인스턴스

<%= Html.MenuLink<WhateverController>(c => c.WhateverAction(), "Whatever") %> 

을 현재 페이지와 링크 된 페이지가 동일하면 active의 클래스가 출력 된 링크에 연결됩니다. 가장 좋은 방법은 현재 요청에 대한 RouteValueDictionary의 내용을 도우미 메서드에 제공된 식의 결과와 비교하는 것입니다. 그러나 두 개의 항목이 같은지 비교하는 좋은 방법을 알 수는 없습니다.

간단한 방법이 있나요? 나는 효과적으로 다음과 같은 방법을 완료하려면 : 내가 사용 시도

public static string MenuLink<T>(this HtmlHelper html, Expression<Action<T>> action, string linkText) where T : Controller 
{ 
    // var link = html.ActionLink<T>(action, linkText, new {}); // Not important yet 

    var routeValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression<T>(action); // Might change? 
    var currentRouteVals = html.ViewContext.RouteData.Values; 
    bool isActivePage = /* are the contents of routeValues also 
          inside currentRouteValues? */ 

    var tb = new TagBuilder("li"); 
    // Continues... 
} 

비교 (==)가 내장되어 있지만, 기본 평등 구현을 사용하고 있다는 것, 따라서 그들이 때문에 false를 돌려줍니다 같은 인스턴스가 아닙니다. 나는 또한 다음을 시도했다 :

bool isActivePage = routeValues.All(x => currentRouteVals.ContainsValue(x)); 

그러나 작동하지 않는다. 나는 완전히 잘못된 나무를 짖고 있니?

답변

3

바하마, 내가 질문을 게시 한 다음 대답을 알아 낸다. 다른 사람이이 문제에 직면 할 경우를 대비하여 여기에 게시하십시오.

bool isActivePage = routeValues.All(x => x.Value.ToString() == (currentRouteVals[x.Key].ToString())); 

이 원래없는 문자열로, 객체로 비교되었다 밝혀 다음과 같이 내가 필요 라인이었다. 문자열로 변환하면 희망에 따라 비교되고 이제는 모두 잘됩니다.

이러한 방식으로 비교해야합니다. 다른 방법으로 비교해 보면 RouteValueDictionary에 관심있는 항목 (예 : 'id'값)이 포함될 수 있습니다. 또는 적어도 그것은 내가 지금 그것을 어떻게 이해하고 있는지입니다. 또한 실험은

2

난 그냥 같은 문제가 발생하여 허용 대답보고 있었다 그것은 것 발견 ... 내가이를 다시해야 할 수도 있습니다 : 예외가 키가 존재하지 않은 경우

  • 원인 두 번째 routeValues ​​목록
  • 은 대개 대소 문자를 구분합니다. 일반적으로 Microsoft URI에는 해당하지 않습니다.
  • 키가 두 번째 목록에 있지만 첫 번째 목록에없는 경우 목록은 동일하지 않은 것으로 비교됩니다.

    public static bool AreEqual(this RouteValueDictionary rvdA, RouteValueDictionary rvdB) 
    { 
        var Equal = 
         new Func<RouteValueDictionary, RouteValueDictionary, bool>((a, b) => a.All(kvp => 
         { 
          object val = b[kvp.Key]; 
          return val != null && kvp.Value.ToString().Equals(val.ToString(), StringComparison.InvariantCultureIgnoreCase); 
         }));             
    
        return rvdA.Count == rvdB.Count && Equal(rvdA, rvdB) && Equal(rvdB, rvdA); 
    } 
    
    :

이 솔루션은 오프 RouteValueDictionary의 자체 포함 된 확장 방법으로 언급 된 문제를 해결