ASP.NET 5 MVC 6 中的 TagBuilder InnerHtml

TagBuilder InnerHtml in ASP.NET 5 MVC 6

在我看来,从 beta7 开始,TagBuilder 发生了重大的重大变化,但公告库中没有提及它们。

特别是 .ToString 不再呈现标签生成器,它只是 returns 类型的名称。 以前我们可以在 HtmlHelper 扩展中做这样的事情来构建嵌套的 html 元素:

var li = new TagBuilder("li");
li.AddCssClass("inactive");
var span = new TagBuilder("span");
span.SetInnerText(somestring);
li.InnerHtml = span.ToString();

.InnerHtml 现在不再接受字符串,因为它现在是 IHtmlContent

但由于 .ToString() 不呈现标签,这也不起作用:

li.InnerHtml = new HtmlString(span.ToString())

它仅呈现为 "Microsoft.AspNet.Mvc.Rendering.TagBuilder",类型的名称。

我在 TagBuilder 上没有看到任何新方法来提供所需的功能。 我错过了什么?我现在如何使用 TagBuilder 构建复杂的嵌套 html?

因为 TagBuilder 现在实现了 IHtmlContent,你应该可以直接使用它,而不用做 .ToString().

var li = new TagBuilder("li");
li.AddCssClass("inactive");
var span = new TagBuilder("span");
span.SetInnerText(somestring);
li.InnerHtml = span;

Beta 7 当前实现的真正问题是没有简单的方法将两个子标签构建器内容附加到一个父标签构建器内容。您可以关注 GitHub.

上的讨论

目前的提议是让InnerHtml不可分配,而是支持Append。这将在 Beta 8.

中实现

Beta 7 中的解决方法是使用 StringWriter 调用 parent.WriteTo 将其转换为 string

Beta 8 通过向标记助手添加 Append() 方法解决了这个问题。

对于 beta 7,解决方案是使用 BufferedHtmlContent() class,但由于它不可访问,我们必须做一些额外的工作。

private class MyBufferedHtmlContent : IHtmlContent
{
    internal List<IHtmlContent> Entries { get; } = new List<IHtmlContent>();

    public MyBufferedHtmlContent Append(IHtmlContent htmlContent)
    {
        Entries.Add(htmlContent);
        return this;
    }

    public void WriteTo(TextWriter writer, IHtmlEncoder encoder)
    {
        foreach (var entry in Entries)
        {
            entry.WriteTo(writer, encoder);
        }
    }
}

用法:

TagBuilder firstChild = new TagBuilder("input");
firstChild.MergeAttribute("type", "hidden");
firstChild.MergeAttribute("name", "Ids");
firstChild.TagRenderMode = TagRenderMode.SelfClosing;

TagBuilder secondChild = new TagBuilder("input");
secondChild.MergeAttribute("type", "hidden");
secondChild.MergeAttribute("name", "Ids");
secondChild.TagRenderMode = TagRenderMode.SelfClosing;

var innerHtml = new MyBufferedHtmlContent();
innerHtml.Append(firstChild);
innerHtml.Append(secondChild);
TagBuilder parent = new TagBuilder("div");
parent.InnerHtml = innerHtml;

使用 MVC 6,在撰写本文时,Tagbuiler.InnerHtml 确实不再有 setter。它有一些方法来附加元素。例如你可以写:

var container = new TagBuilder("div");
var input = new TagBuilder("input");

container.InnerHtml.AppendHtml(input);

@Memet 奥尔森

我的所有自定义 TagHelper 都因更新到 4.6.1 (1.0.0-rc2) 而损坏。 InnerHtml.Append() 将不再接受 TagBuilder。

相反,应使用 AppendHtml() 方法:

var container = new TagBuilder("div");
var input = new TagBuilder("input");

container.InnerHtml.AppendHtml(input);

第二次错误修复[here]

基于@Mihai 的回答显示 StringWriter 方法的实际代码:

// Create tag builder
var builder = new TagBuilder("img");
//...
// Render tag approach also changed in .NetCore
builder.TagRenderMode = TagRenderMode.SelfClosing;

//Create the StringWriter and make TagBuilder "WriteTo" it
var stringWriter = new System.IO.StringWriter();
builder.WriteTo(stringWriter, HtmlEncoder.Default);
var tagBuilderIsFinallyAStringNow = stringWriter.ToString();

失去了span.SetInnerText(somestring);现在可以做到

span.InnerHtml.SetContent(somestring);

使用 Microsoft.AspNetCore.Html.HtmlContentBuilderExtensions.

这是从 4.​​7 和 AspNetCore 2.0.1 的角度来看的。