3

我已经写了一个扩展方法给HtmlHelper(派生自active menu item - asp.net mvc3 master page)。这使我可以输出当前页面的cssclass“active”。ASP.NET MVC3:如何访问HtmlHelper扩展方法中作为routeValues匿名类型传递的参数?

但是,我现在重构使用区域,所以该方法不再有效,因为我有控制器称为家庭和行动称为索引在几个领域。所以我一直试图通过检查当前区域,并将区域作为路由值匿名类型的一部分传递进行排序。

所以我的扩展方法现在看起来是这样的:

public static MvcHtmlString NavigationLink<T>(this HtmlHelper<T> htmlHelper, string linkText, string actionName, string controllerName, dynamic routeValues) 
{ 
    string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller"); 
    string currentArea = htmlHelper.ViewContext.RouteData.DataTokens["Area"] as string; 
    if (controllerName == currentController && IsInCurrentArea(routeValues,currentArea)) 
    { 
     return htmlHelper.ActionLink(
      linkText, 
      actionName, 
      controllerName, 
      (object)routeValues, 
      new 
      { 
       @class = "active" 
      }); 
    } 
    return htmlHelper.ActionLink(linkText, actionName, controllerName, (object)routeValues, null); 
} 

private static bool IsInCurrentArea(dynamic routeValues, string currentArea) 
{ 
    string area = routeValues.Area; //This line throws a RuntimeBinderException 
    return string.IsNullOrEmpty(currentArea) && (routeValues == null || area == currentArea); 
} 

我改变routeValues动态的类型,这样我可以编译以下行:

弦面积= routeValues.Area;

我可以看到调试器中的routeValues对象的Area属性,但只要我访问它,我得到一个RuntimeBinderException。

有没有更好的方式来访问匿名类型的属性?

回答

1

我已经知道我可以使用RouteValueDictionary上的构造函数,它允许我轻松地查找Area属性。

我也注意到了,我试图使用控制器价值,以及让我的代码现在看起来像下面的问题复杂化:

public static MvcHtmlString NavigationLink<T>(this HtmlHelper<T> htmlHelper, string linkText, string actionName, string controllerName, object routeValues) 
    { 
     string currentArea = htmlHelper.ViewContext.RouteData.DataTokens["Area"] as string; 

     if (IsInCurrentArea(routeValues, currentArea)) 
     { 
      return htmlHelper.ActionLink(
       linkText, 
       actionName, 
       controllerName, 
       routeValues, 
       new 
       { 
        @class = "active" 
       }); 
     } 
     return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, null); 
    } 

    private static bool IsInCurrentArea(object routeValues, string currentArea) 
    { 
     if (routeValues == null) 
      return true; 

     var rvd = new RouteValueDictionary(routeValues); 
     string area = rvd["Area"] as string ?? rvd["area"] as string; 
     return area == currentArea; 
    } 
相关问题