附加htmlAttributes的MVC自定义助手

时间:2017-07-20 21:55:27

标签: c# asp.net-mvc html-helper

我有一个自定义助手类来突出显示所选的菜单项

<li class="nav-item">
    @Html.MenuLink("Contact000", "Contact", "Home", new { @class = "nav-link" })
</li>   

如果选择条件为true,我想使用helper htmlattributes并附加到CSS。我看过Similiar question,但无法使用

找到问题
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

这是我的代码

public static MvcHtmlString MenuLink(this HtmlHelper helper, string text, string action, string controller, object htmlAttributes)
{
    var routeData = helper.ViewContext.RouteData.Values;
    var currentController = routeData["controller"];
    var currentAction = routeData["action"];

    var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

    if (String.Equals(action, currentAction as string,
        StringComparison.OrdinalIgnoreCase)
        &&
        String.Equals(controller, currentController as string,
        StringComparison.OrdinalIgnoreCase))
    {
        if (attrs.ContainsKey("class"))
        {
            attrs["class"] += " " + "currentMenuItem";
        }

        return helper.ActionLink(text, action, controller, attrs);
    }

    return helper.ActionLink(text, action, controller, htmlAttributes);
}
使用

 var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

我可以附加属性。

当我返回helper.actionlink时,没有正确解析attrs,下面是生成的html,

<li class="nav-item">
    <a Count="1" Keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]" Values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]" href="/Home/Contact?Length=4">Contact000</a>
</li>

我想了解以下内容,

<li class="nav-item">
    <a class="nav-link currentMenuItem" href="/Home/Contact">Contact000</a>
</li>

如何将attrs转换回htmlAttributes以使助手工作?

1 个答案:

答案 0 :(得分:2)

您可以使用object htmlAttributes创建RouteValueDictionary。然后,您可以像使用任何其他IDictionary<TKey, TValue>界面一样追加值。

IDictionary<string, object> attrs = new RouteValueDictionary(htmlAttributes);

string key = "key";
string oldValue;
if (attrs.TryGetValue(key, out oldValue))
{
    // append to value
    attrs[key] = oldValue + "string to append";
}
else
{
    // key not in attrs, handle accordingly
}

完整示例:

using System.Web.Routing;

public static MvcHtmlString MenuLink(this HtmlHelper helper,
    string text, string action, string controller, object htmlAttributes)
{
    var routeData = helper.ViewContext.RouteData.Values;
    var currentController = routeData["controller"];
    var currentAction = routeData["action"];

    IDictionary<string, object> attrs = new RouteValueDictionary(htmlAttributes);

    if (String.Equals(action, currentAction as string,
            StringComparison.OrdinalIgnoreCase)
        && String.Equals(controller, currentController as string,
                StringComparison.OrdinalIgnoreCase))
    {
        string clazz;
        if (attrs.TryGetValue("class", out clazz))
        {
            attrs["class"] = clazz + " " + "currentMenuItem";
        }
        // do you need to handle the case when there is no "class" attribute?

        return helper.ActionLink(text, action, controller, attrs);
    }

    return helper.ActionLink(text, action, controller, htmlAttributes);
}

编辑:我发现了问题的实际问题,你使用的是错误的 Html.ActionLink超载。

当您使用ActionLink(HtmlHelper, String, String, Object, Object)重载时,您当前正在使用ActionLink(HtmlHelper, String, String, String, RouteValueDictionary, IDictionary<String, Object>)重载。

helper.ActionLink(text, action, controller, routeValues: null, htmlAttributes: attrs);