MVC 自定义助手附加 htmlAttributes

MVC custom helper appending htmlAttributes

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

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

我想使用辅助 html 属性并在所选条件为真时附加到 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);

我可以附加到属性。

当我return helper.actionlink 属性没有正确解析时,下面是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 转换回 html属性以便助手工作?

您可以创建一个 RouteValueDictionary using object htmlAttributes. Then you can append a value like you would with any other 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) overload, when you should be using the ActionLink(HtmlHelper, String, String, String, RouteValueDictionary, IDictionary<String, Object>) 重载。

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