TagBuilder InnerHtml в ASP.NET 5 MVC 6

Мне кажется, что в TagBuilder произошли серьезные переломные изменения в бета-версии 7, и о них ничего не говорится в репозитории анонсов.

В частности.ToString больше не отображает тэгбилдер, он просто возвращает имя типа. ранее мы могли делать такие вещи внутри наших расширений 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 для обеспечения необходимой функциональности. Что мне не хватает? Как я могу создать сложный вложенный HTML с TagBuilder сейчас?

6 ответов

Решение

Так как TagBuilder сейчас реализует IHtmlContent, вы должны быть в состоянии использовать его напрямую, не делая .ToString(),

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

Реальная проблема с текущей реализацией в бета-версии 7 заключается в том, что не существует простого способа добавить два содержимого компоновщика дочерних тегов к родительскому. Вы можете следить за обсуждением на GitHub.

Текущее предложение состоит в том, чтобы сделать InnerHtml не присваивается, но поддерживается Append вместо. Это должно быть реализовано в бета-версии 8.

Обходной путь в бета-версии 7 заключается в вызове parent.WriteTo с StringWriter преобразовать его в string,

Используя MVC 6, на момент написания Tagbuiler.InnerHtml действительно больше не имеет сеттера. Вместо этого у него есть несколько методов для добавления элемента. Например, вы можете написать:

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

container.InnerHtml.AppendHtml(input);

Потеряв span.SetInnerText(somestring); теперь можно делать

span.InnerHtml.SetContent(somestring);

с помощью Microsoft.AspNetCore.Html.HtmlContentBuilderExtensions,

Это с точки зрения 4.7 с AspNetCore 2.0.1.

Основываясь на ответе @ Михая, чтобы показать действительный код для подхода 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();

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

2-е исправление [здесь]

Beta 8 решила эту проблему, добавив Append() метод помечать помощников.

Для бета-версии 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;
Другие вопросы по тегам