web-dev-qa-db-de.com

TagBuilder InnerHtml in ASP.NET 5 MVC 6

Es scheint mir, dass es ab Beta7 große Änderungen in TagBuilder gibt, ohne dass dies im Ankündigungs-Repo erwähnt wird.

Insbesondere .ToString rendert den Tagbuilder nicht mehr, sondern gibt nur den Namen des Typs zurück.

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

.InnerHtml akzeptiert jetzt keine Zeichenfolge mehr, da es jetzt IHtmlContent ist

aber da .ToString () das Tag nicht rendert, funktioniert das auch nicht:

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

es stellt lediglich den Namen des Typs "Microsoft.AspNet.Mvc.Rendering.TagBuilder" dar.

Ich sehe keine neuen Methoden in TagBuilder, um die benötigte Funktionalität bereitzustellen .. Was fehlt mir? Wie kann ich jetzt mit TagBuilder komplexe verschachtelte HTML-Dateien erstellen?

16
Joe Audette

Da TagBuilder jetzt IHtmlContent implementiert, sollten Sie es direkt verwenden können, ohne .ToString() auszuführen.

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

Das eigentliche Problem der aktuellen Implementierung in Beta 7 besteht darin, dass es nicht einfach ist, zwei untergeordnete Tag-Builder-Inhalte an einen übergeordneten anzufügen. Sie können die Diskussion auf GitHub verfolgen.

Der aktuelle Vorschlag sieht vor, InnerHtml nicht zuweisbar zu machen, sondern stattdessen Append zu unterstützen. Dies soll in Beta 8 implementiert werden.

Die Problemumgehung in Beta 7 besteht darin, parent.WriteTo mit einer StringWriter aufzurufen, um es in eine string zu konvertieren.

Mit MVC 6 hat Tagbuiler.InnerHtml zum Zeitpunkt des Schreibens tatsächlich keinen Setter mehr Stattdessen gibt es einige Methoden, um das Element anzufügen. Zum Beispiel könnten Sie schreiben:

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

container.InnerHtml.AppendHtml(input);
15
Memet Olsen

Aufbauend auf der Antwort von @ Mihai, um den Code für den StringWriter-Ansatz zu zeigen:

// 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();
2
goamn

@Memet Olsen

Alle meine benutzerdefinierten TagHelpers brachen mit einem Update auf 4.6.1 (1.0.0-rc2). InnerHtml.Append () akzeptiert keinen TagBuilder mehr.

Stattdessen sollte die AppendHtml () -Methode verwendet werden:

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

container.InnerHtml.AppendHtml(input);

2. Bugfix [hier]

2
Paul McCombie

Beta 8 hat dieses Problem gelöst, indem eine Append()-Methode hinzugefügt wurde, um Helfer zu markieren.

Für Beta 7 wäre die Lösung die Verwendung der BufferedHtmlContent()-Klasse. Da sie jedoch nicht zugänglich ist, müssen wir zusätzliche Arbeit verrichten.

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

Verwendungszweck:

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;
2

Nachdem Sie span.SetInnerText(somestring); verloren haben, ist dies jetzt möglich

span.InnerHtml.SetContent(somestring);

mit Microsoft.AspNetCore.Html.HtmlContentBuilderExtensions.

Dies kommt aus einer Perspektive von 4.7 mit AspNetCore 2.0.1.

2
A James