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;