ASP.NET 5 MVC 6中的TagBuilder InnerHtml

时间:2015-09-05 18:32:11

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc

在我看来,从beta7开始,TagBuilder发生了重大变化,在公告回购中没有提到它们。

具体来说.ToString不再呈现tagbuilder,它只返回类型的名称。 以前我们可以在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?

6 个答案:

答案 0 :(得分:15)

由于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 中的解决方法是使用parent.WriteTo致电StringWriter将其转换为string

答案 1 :(得分:15)

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

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

container.InnerHtml.AppendHtml(input);

答案 2 :(得分:3)

@Memet Olsen

我的所有自定义TagHelpers都更新了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]

答案 3 :(得分:2)

Beta 8通过添加Append()方法来标记助手来解决此问题。

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

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;

答案 4 :(得分:2)

以@ 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();

答案 5 :(得分:2)

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

span.InnerHtml.SetContent(somestring);

使用Microsoft.AspNetCore.Html.HtmlContentBuilderExtensions

这是从4.7的角度来看AspNetCore 2.0.1。