提问者:小点点

标记生成器的问题。参数null的MergeAttribute


我想使用Razor的特性,在属性值为null的情况下,不在标记内生成属性输出。所以当剃刀相遇时

public static MvcHtmlString WriteHeader(this HtmlHelper html, string s, int? hLevel = 1, object htmlAttributes = null)
{
    if ((hLevel == null) || 
        (hLevel < 1 || hLevel > 4) ||
        (s.IsNullOrWhiteSpace()))
        return new MvcHtmlString("");

    string cssClass = null, cssId = null, cssStyle = null;

    if (htmlAttributes != null)
    {
        var T = htmlAttributes.GetType();

        var propInfo = T.GetProperty("class");
        var o = propInfo.GetValue(htmlAttributes);
        cssClass = o.ToString().IsNullOrWhiteSpace() ? null : o.ToString();

        propInfo = T.GetProperty("id");
        o = propInfo.GetValue(htmlAttributes);
        cssId = o.ToString().IsNullOrWhiteSpace() ? null : o.ToString();

        propInfo = T.GetProperty("style");
        o = propInfo.GetValue(htmlAttributes);
        cssStyle = o.ToString().IsNullOrWhiteSpace() ? null : o.ToString();
    }

    var hTag = new TagBuilder("h" + hLevel);

    hTag.MergeAttribute("id", cssId);
    hTag.MergeAttribute("class", cssClass);
    hTag.MergeAttribute("style", cssStyle);
    hTag.InnerHtml = s;

    return new MvcHtmlString(hTag.ToString());
}

我发现,尽管“类”和“样式”属性为空值,TagBuilder仍然把它们作为空字符串,比如

我的问题是——这种行为真的应该发生吗?如何使用TagBuilder实现空值的缺席属性?

我在VS2013中尝试过这个,MVC5。


共1个答案

匿名用户

TagBuilder写入所有指定的属性,除了空的或空的“id”属性。以下是在内部使用类TagBuilder的代码:

    private void AppendAttributes(StringBuilder sb)
    {
        foreach (var attribute in Attributes)
        {
            string key = attribute.Key;
            if (String.Equals(key, "id", StringComparison.Ordinal /* case-sensitive */) && String.IsNullOrEmpty(attribute.Value))
            {
                continue; // DevDiv Bugs #227595: don't output empty IDs
            }
            string value = HttpUtility.HtmlAttributeEncode(attribute.Value);
            sb.Append(' ')
                .Append(key)
                .Append("=\"")
                .Append(value)
                .Append('"');
        }
    }

您可以按如下方式创建Html扩展:

    public static MvcHtmlString WriteHeader(this HtmlHelper html, string s, int? hLevel = 1, object htmlAttributes = null)
    {
        var hTag = new TagBuilder("h" + hLevel);
        hTag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        hTag.InnerHtml = s;
        return MvcHtmlString.Create(hTag.ToString());
    }

并且,例如,可以如下使用:

@Html.WriteHeader("hello1", 1)
@Html.WriteHeader("hello2", 2, new { @class = string.Empty, style = string.Empty })
@Html.WriteHeader("hello3", 3, new { id = "id3", @class = "css3", style = "style3" })

生成以下HTML代码:

<h1>hello1</h1>
<h2 class="" style="">hello2</h2>
<h3 class="css3" id="id3" style="style3">hello3</h3>