web-dev-qa-db-fra.com

TagBuilder InnerHtml dans ASP.NET 5 MVC 6

Il me semble que TagBuilder a subi des modifications majeures à partir de la version 7 sans aucune mention à ce sujet dans le référentiel d'annonces.

Concrètement, .ToString ne rend plus le constructeur de balises, mais renvoie simplement le nom du type . Auparavant, nous pouvions faire de telles choses dans nos extensions HtmlHelper pour construire des éléments HTML imbriqués:

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

.InnerHtml n'accepte plus la chaîne parce que c'est maintenant IHtmlContent

mais puisque .ToString () ne rend pas la balise, cela ne fonctionne pas non plus:

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

il ne fait que rendre "Microsoft.AspNet.Mvc.Rendering.TagBuilder", le nom du type.

Je ne vois aucune nouvelle méthode sur TagBuilder pour fournir les fonctionnalités nécessaires . Qu'est-ce qui me manque? Comment puis-je construire un code HTML imbriqué complexe avec TagBuilder maintenant?

16
Joe Audette

Étant donné que TagBuilder implémente maintenant IHtmlContent, vous devriez pouvoir l’utiliser directement, sans utiliser .ToString().

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

Le vrai problème avec l’implémentation actuelle dans Beta 7 est qu’il n’existe pas de moyen facile d’ajouter deux contenus de générateur de balises enfant à un contenu parent. Vous pouvez suivre la discussion sur GitHub .

La proposition actuelle est de rendre InnerHtml non assignable, mais de supporter Append à la place. Ceci est destiné à être implémenté dans Beta 8.

La solution de contournement dans Beta 7 consiste à appeler parent.WriteTo avec un StringWriter pour le convertir en un string.

15

En utilisant MVC 6, Tagbuiler.InnerHtml n’a en effet plus de setter au moment de la rédaction. Il a quelques méthodes à la place pour ajouter l'élément. Par exemple, vous pouvez écrire:

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

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

S'appuyant sur la réponse de @ Mihai pour afficher le code actuel de l'approche 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();
2
goamn

@Memet Olsen

Tous mes TagHelpers personnalisés ont éclaté avec une mise à jour à la version 4.6.1 (1.0.0-rc2). InnerHtml.Append () n'acceptera plus un TagBuilder.

Au lieu de cela, la méthode AppendHtml () devrait être utilisée:

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

container.InnerHtml.AppendHtml(input);

2ème correction de bug [ici]

2
Paul McCombie

La bêta 8 a résolu ce problème en ajoutant une méthode Append() pour baliser les assistants.

Pour la version 7, la solution serait d’utiliser la classe BufferedHtmlContent(), mais comme elle n’est pas accessible, nous devons faire un travail supplémentaire.

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

Usage:

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
Leonardo Herrera