Question

J'écris la RenderContents() méthode de mon contrôle serveur ASP.NET. La méthode utilise un objet HtmlTextWriter pour restituer le contenu en sortie. Pour le contrôle que j'écris, utiliser les méthodes de StringBuilder semble nécessiter beaucoup de lignes de code pour ouvrir et fermer chaque balise et ajouter chaque attribut au flux. En fin de compte, je sens que je vais finir avec un code beaucoup plus long que nécessaire.

Je pensais que si j'utilisais une classe chaînable telle que <=>, mon code serait beaucoup plus propre à la lecture et plus facile à écrire.

Ce que je me demandais, at-il une raison d'utiliser l'objet <=> pour afficher le contenu de l'ensemble de mon contrôle? Hormis les vérifications de sécurité (je suppose), cela inclut de vous assurer que vous n'écrivez pas les étiquettes dans le mauvais ordre ou que vous ne créez pas de balisage non valide. Je ne vois pas de raison.

Il semble qu'il serait plus facile de faire quelque chose comme ceci:

protected override void RenderContents(HtmlTextWriter output)
{
    StringBuilder s = new StringBuilder();
    s.Append("lots")
     .Append("of")
     .Append("strings");

    output.BeginRender();
    output.Write(s.ToString());
    output.EndRender();
}

Y a-t-il une raison pour laquelle cela serait une mauvaise idée?

Mettre à jour
En réponse à la réponse de Mehrdad Afshari :
 Je ne pensais pas beaucoup aux besoins en mémoire d'un objet <=> séparé instancié. Pourquoi ne pas créer un wrapper pour HtmlTextWriter afin qu’il puisse être chaîné afin qu’une chaîne supplémentaire ne soit pas créée?

public class ChainedHtmlTextWriter
{
    private HtmlTextWriter _W;
    public ChainedHtmlTextWriter(HtmlTextWriter writer)
    {
        _W = writer;
    }

    public ChainedHtmlTextWriter Write<T>(T value) 
    { 
        _W.Write(value); 
        return this; 
    }

    public ChainedHtmlTextWriter WriteLine<T>(T value)
    {
        _W.WriteLine(value);
        return this;
    }
}
Était-ce utile?

La solution

Je travaille sur une application dans laquelle les développeurs ont suivi l'horrible chemin que vous explorez. Cela nous ramène à l'époque où vous deviez écrire vos propres dll ISAPI qui crachaient du code HTML. Travailler est un casse-tête permanent. Si votre code est principalement constitué de chaînes, alors quelque chose ne va pas.

La plupart du code de ce type que je modifie, j’instancie les objets serveur, configure leurs propriétés comme il convient, puis leur indique .RenderControl (writer). Cela rend le code beaucoup plus facile à lire et à utiliser. Si les frais généraux entraînent des problèmes de performances, je suis prêt à les accepter (en fait, l'application est généralement plus rapide une fois les modifications apportées. Donc, de façon anecdotique, ce n'est pas le cas, mais je n'ai pas présenté de profil. mon code).

Un inconvénient simple à coder en dur vos documents en chaînes est le changement des normes HTML. Le code sur lequel je travaille a été écrit en 04/05, et depuis lors & Lt; BR & Gt; est devenu < br / > et les balises html majuscules ne sont plus kasher, etc. S'ils utilisaient des contrôles serveur, ceux-ci ont changé leur code HTML en sortie sans que nous ayons besoin de faire quoi que ce soit. Ce n’est qu’un exemple simple.

EDIT: Oh, et btw, BeginRender et EndRender n’ont aucune implémentation. Ce sont des espaces réservés que vous pouvez remplacer et fournir des fonctionnalités personnalisées dans une classe dérivée de HtmlTextWriter.

EDIT2: Parfois, il est un peu difficile de toujours d’utiliser les contrôles serveur, comme pour les conteneurs et autres. Je ferais beaucoup de .Controls.Add () et puis rendrais le conteneur plus tard. Alors parfois, je fais ceci:

writer.AddAttribute(HtmlTextWriterAttribute.Class, "myContainerClass");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
// do some stuff, .RenderControl on some other controls, etc.
writer.RenderEndTag();

Comme mentionné, cela restituera le code HTML correct même si le code HTML d'une div change à l'avenir, car je n'ai aucune chaîne codée en dur.

Autres conseils

En termes de performances, cela nécessitera davantage de copies de chaînes. HtmlTextWriter écrit directement dans le tampon de sortie. StringBuilder d’autre part, a son propre tampon. Lorsque vous appelez ToString sur output.Write, une nouvelle chaîne doit être créée. Elle sera ensuite écrite dans le tampon de sortie par <=>. Cela nécessite beaucoup de travail.

Je ne pense pas que vous devriez appeler BeginRender / EndRender, cela est fait par la page.

Je ne vois pas comment l'utilisation du générateur de chaînes permettrait d'économiser du travail à l'aide des méthodes propres à HtmlTextWriters.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top