ActionLink 扩展方法 MVC5 中的 htmlAttributes
htmlAttributes in ActionLink Extension method MVC5
我正在使用扩展方法在菜单上的活动链接上维护 css class。
但是我遇到了 htmlAttributes 和对象值导致错误的问题。
我的 Razor 页面中有以下内容,但我不明白我应该如何解析 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);
}
将参数从 IDictionary<object, string> htmlAttributes
更改为 object htmlAttributes
,因为您将属性作为对象传递。
然后您可以使用
转换对象
var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
但是,您的扩展方法中没有任何地方使用过这些属性。根据当前的控制器和动作名称,您所有的生成都是 class = "currentMenu"
。如果您打算添加属性加上 class 名称(取决于条件),则可以使用
attributes.Add("class", "currentMenu");
允许定义路由值和 html 属性并有条件地包含 "currentMenu"
class 名称的完整方法应该是
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);
}
旁注:您还应该考虑根据内置 ActionLink()
方法包括其他重载以接受 RouteValueDictionary routeValues
和 IDictionary<String, Object>) htmlAttributes
,并且您可以检查 source code查看各种重载如何落入其他重载。
我正在使用扩展方法在菜单上的活动链接上维护 css class。
但是我遇到了 htmlAttributes 和对象值导致错误的问题。
我的 Razor 页面中有以下内容,但我不明白我应该如何解析 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);
}
将参数从 IDictionary<object, string> htmlAttributes
更改为 object htmlAttributes
,因为您将属性作为对象传递。
然后您可以使用
转换对象var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
但是,您的扩展方法中没有任何地方使用过这些属性。根据当前的控制器和动作名称,您所有的生成都是 class = "currentMenu"
。如果您打算添加属性加上 class 名称(取决于条件),则可以使用
attributes.Add("class", "currentMenu");
允许定义路由值和 html 属性并有条件地包含 "currentMenu"
class 名称的完整方法应该是
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);
}
旁注:您还应该考虑根据内置 ActionLink()
方法包括其他重载以接受 RouteValueDictionary routeValues
和 IDictionary<String, Object>) htmlAttributes
,并且您可以检查 source code查看各种重载如何落入其他重载。