Quelle est la meilleure façon de créer du HTML en code C #? [fermé]

15

J'ai la conviction que le balisage doit rester dans le balisage et non dans le code derrière.

Je suis arrivé à une situation où je pense qu'il est acceptable de construire le code HTML dans le code derrière. J'aimerais avoir un certain consensus sur les bonnes ou les meilleures pratiques.

Quand est-il acceptable de construire du HTML dans le code derrière? Quelle est la meilleure méthode pour créer ce html? (exemple: Strings, StringBuilder, HTMLWriter, etc.)

Rodney
la source
essayez d'utiliser des modèles et des espaces réservés où vous cracherez ces balises html.
Yusubov
5
Autre option: produire du XML en fonction de votre modèle de données, puis utiliser XSLT pour transformer le XML en HTML.
FrustratedWithFormsDesigner
Je viens de me faire remarquer aujourd'hui C # / XAML pour HTML5, semble prometteur et peut convenir à votre scénario. cshtml5.com
softveda
un problème avec la route XSLT est dans la localisation. Si vous avez besoin de deux langues, vous avez besoin de deux feuilles de style XSLT et gardez-les parallèles. C'est l'enfer. Mieux vaut simplement écrire du HTML dans un fichier texte à partir de C #. utiliser String.Format et $ ".. {variable} ..." avec WPFLocalization?
Erik

Réponses:

12

Est-ce que l'utilisation de quelque chose comme Razor n'est pas applicable ici? Parce que si vous faites beaucoup de génération HTML en utilisant un moteur de vue, cela peut être beaucoup plus facile. Il a également été conçu pour être utilisé en dehors d'ASP.NET.

Cependant, parfois, ce n'est pas ce dont vous avez besoin. Avez-vous envisagé d'utiliser la classe TagBuilder qui fait partie de .net (mvc)? Il y a aussi le HtmlWriter dans System.Web.UI (pour les formulaires Web). Je recommanderais l'un d'entre eux si vous faites Controlsou Html Helpers.

Daniel Little
la source
3
+1, si vous avez besoin de modèles dans un rasoir d'application, c'est la voie à suivre. Consultez razorengine @ nuget.org/packages/RazorEngine si vous avez besoin d'une excellente option pour monter le rasoir dans une application nonasp.net.
Wyatt Barnett
1
J'ai une exigence similaire où j'ai besoin de générer du HTML (des charges de celui-ci) dans une bibliothèque de classes. Je veux utiliser le rasoir pour cela, mais j'ai du mal à comprendre comment maintenir les fichiers cshtml dans une dll. Comment peut-il se regrouper?
Yashvit
Vous pouvez simplement passer n'importe quelle chaîne stackoverflow.com/questions/3628895/…
Daniel Little
14

J'utiliserais le pack d'agilité HTML pour assembler du HTML, puis l'écrire dans un fichier texte.

De nombreuses heures de travail ont été nécessaires pour rendre le pack d'agilité Html robuste et compatible HTML.

Je pense qu'il comprend même un exemple d'application qui génère du HTML.

Depuis la page d'accueil:

Exemples d'applications:

Correction ou génération de page. Vous pouvez corriger une page comme vous le souhaitez, modifier le DOM, ajouter des nœuds, copier des nœuds, eh bien ... vous l'appelez.

Jim G.
la source
5

J'utiliserais htmltags pour créer du HTML.

Exemple:

var tag = new HtmlTag("span")
    .Text("Hello & Goodbye")
    .AddClass("important")
    .Attr("title", "Greetings")

Et puis CSQuery si je veux analyser HTML

Exemple:

dom.Select("div > span")
    .Eq(1)
    .Text("Change the text content of the 2nd span child of each div");
jgauffin
la source
2

Il existe, bien sûr, des bibliothèques, telles que HTML Agility Pack, qui peuvent vous aider dans ces efforts.

Si vous ne voulez vraiment pas utiliser une bibliothèque existante et que vous voulez du code simple, bas et sale, j'aime l'idée d'abstraire certains des comportements comme une réponse précédente l'a déclaré. J'aime également l'idée d'utiliser un StringBuilder sous-jacent, par opposition à une chaîne pour quelques raisons:

  1. Les chaînes sont moins efficaces que le générateur de chaînes
  2. StringBuilder est une structure de données indexable,

Si je n'ai pas besoin d'un moteur HTML massivement conçu, je construirais une interface simple et intuitive

AddLineBreak();
AddSimpleTag(string tagName);
AddSimpleTagAt(string tagName, string content, int index);
Output();
Tim C
la source
1
La structure des données indexables est convaincante, mais je ne m'inquiéterais pas trop de l'efficacité: codinghorror.com/blog/2009/01/…
Jim G.
1
Je me suis un peu penché plusieurs fois sur la lourdeur des cordes, en particulier VRAIMENT de grosses cordes. Les StringBuilders sont plus efficaces en mémoire et en processeur lorsqu'ils sont volumineux. Donc, dans une implémentation comme celle-ci, où le HTML peut devenir très gros, je commencerais par un StringBuilder. S'il y avait une garantie que le HTML n'allait pas devenir très gros, une chaîne serait certainement adéquate.
Tim C
1
Eh bien, si le HTML peut devenir vraiment gros, je recommanderais certainement le pack HTML Agility. [J'ai en fait recommandé le pack d'agilité HTML deux minutes avant vous. :)]
Jim G.
1

Si vous finissez par n'utiliser que des chaînes, n'oubliez pas d'échapper tous les caractères réservés HTML dans vos données de sortie.

&    &
>    >
<    &lt;
"    &quot;
'    &apos;

Je recommande cependant d'utiliser une classe ou une bibliothèque HTML au lieu de travailler directement avec des chaînes. HTMLWriter ressemble à un assez bon début.

Mike Clark
la source
Merci pour cette perspicacité. Pour qui que ce soit, c'est ce que j'utilise pour passer les valeurs d'une table de données dans un modèle d'élément. La clé est (comme le suggère Mike Clark) d'être au courant du HTML: <asp: Button ID = "btnEdit" CssClass = "btnmaatwerksmall" runat = "server" Text = "Wijzig" OnClientClick = '<% # String.Format ("OpenChildInEnterprise (& apos; {0} & apos;, & apos; {1} & apos;, & apos; {2} & apos;); ", Eval (" Cursus "), Eval (" Omschrijving "), Eval (" Opmerking "))% > '/>
real_yggdrasil
-1

Près de deux ans après la publication d'origine - voici une solution qui a bien fonctionné pour moi. Dans le document cible, je place ce qui suit:

<table>    
    <%:theHtmlTableMomToldYouAbout() %>    //# Where I want my rows of table data to go
</table>

la fonction appelée ressemble à ceci:

    public HtmlString theHtmlTableMomToldYouAbout()
    {
        string content = "";
        HtmlString theEnvelopePlease = null;

        for (int i = 0; i < 5; i++)
        {
            content = content + "<tr><td>The Number Is: " + i + "</td></tr>";
        }
        theEnvelopePlease = new HtmlString(content);
        return theEnvelopePlease;      
    }

Et la sortie résultante dans le navigateur est comme prévu:
Le nombre est: 0
Le nombre est: 1
Le nombre est: 2
Le nombre est: 3
Le nombre est: 4

Lorsque je vais voir la source, je trouve ce qui suit:

<table>
    <tr><td>The Number Is: 0</td></tr>
    <tr><td>The Number Is: 1</td></tr>
    <tr><td>The Number Is: 2</td></tr>
    <tr><td>The Number Is: 3</td></tr>
    <tr><td>The Number Is: 4</td></tr>
</table>
WebFixItMan
la source
1
Je soulignerai que votre solution a beaucoup des mêmes problèmes avec le «contenu» étant une chaîne immuable que ceux décrits dans les messages à faible score de cette question.
-1

FLAMME!

var html = "";
html += "<table class='colorful'>";
foreach(var item in collection) {
     html += "<tr>";
     html += "<td class='boldCell'>" + item.PropWhatever + "</td>";
     // more cells here as needed
     html += "</tr>";
}
html += "</table>";
placeholder1.InnerHtml = html;

Je vais probablement obtenir un vote négatif pour cela, mais en tant qu'ancien concepteur qui a dû modifier le code HTML avant de vraiment en savoir beaucoup sur .NET, le code ci-dessus était beaucoup plus facile à comprendre que les méthodes qui résument la création HTML. Si vous pensez qu'un concepteur pourrait avoir à modifier votre code HTML, utilisez des chaînes simples comme celle-ci.

Quelque chose que je constate que beaucoup de développeurs manquent lorsqu'ils écrivent du HTML dans le code, c'est qu'en HTML, les guillemets simples ou doubles sont autorisés pour les attributs. Donc, au lieu d'échapper à toutes les guillemets dans le code (ce qui semble bizarre aux non-initiés), utilisez simplement des guillemets simples pour les guillemets html à l'intérieur de vos chaînes.


BIEN. Tout ce que vous, les haineux concaténants, cramponnez à mon représentant. Voici la façon «correcte» de le faire sans concaténation de chaînes, mais je maintiens mon opinion que toute page normale avec des tables normales ne présentera aucun problème de performances en dehors d'une échelle ridicule de type Google:

var sb = new System.Text.StringBuilder();
sb.Append("<table class='colorful'>");
foreach (var item in collection)
{
     sb.Append("<tr>");
     sb.Append("<td class='boldCell'>" + item.PropWhatever + "</td>");
     // more cells here as needed
     sb.Append("</tr>");
}
sb.Append("</table>");
placeholder1.InnerHtml = sb.ToString();
Graham
la source
3
-1 utiliser + pour concaténer des chaînes en boucles est la pire chose que vous puissiez faire.
Daniel Little
suite: voir stackoverflow.com/questions/3102806/…
Daniel Little
Eh bien, pour commencer, utiliser à l' +=intérieur d'une boucle de cette façon n'est pas du tout mis à l'échelle; parce que les chaînes sont immuables, vous créez une toute nouvelle chaîne à chaque fois que vous le faites. Utilisez StringBuilderplutôt un .
Robert Harvey
3
Pourquoi les gens qui écrivent du code horrible doivent-ils partager leur code horrible avec d'autres personnes?
Ramhound
3
@Ramhound Qu'en If you think a designer might ever have to tweak your HTML, use simple strings like this.est-il difficile à comprendre? La définition de certains codes horribles est celle qui achète des millisecondes de performances au prix de plusieurs secondes pour bien comprendre. De toute évidence, lorsque vous prévoyez que votre code sera visualisé ou maintenu par le plus petit dénominateur commun d'individu, il est très certainement possible de penser que l'écriture de code plus facile à comprendre ou à modifier est toujours meilleure que le code le plus propre ou le plus performant.
maple_shaft