TagBuilder InnerHtml в ASP.NET 5 MVC 6
Мне кажется, что в TagBuilder есть серьезные изменения в отношении бета-версии 7 без упоминания о них в репортажах объявлений.
В частности. 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 для обеспечения необходимой функциональности.
Что мне не хватает? Как я могу теперь построить сложный вложенный html с TagBuilder?
Ответы
Ответ 1
Поскольку 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
. Это предназначено для реализации в Бета 8.
Обходной путь в Бета 7 состоит в вызове parent.WriteTo
с StringWriter
, чтобы преобразовать его в string
.
Ответ 2
Используя MVC 6, на момент написания, Tagbuiler.InnerHtml
больше не имеет сеттера. У этого есть некоторые методы, чтобы добавить элемент. Например, вы могли бы написать:
var container = new TagBuilder("div");
var input = new TagBuilder("input");
container.InnerHtml.AppendHtml(input);
Ответ 3
Бета-версия 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;
Ответ 4
@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);
2nd bug-fix [здесь]
Ответ 5
Основываясь на ответе @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();