5

RenderContents()ASP.NET サーバー コントロールのメソッドを作成しています。このメソッドは、HtmlTextWriterオブジェクトを使用して出力コンテンツをレンダリングします。私が書いているコントロールの場合、HtmlTextWriterのメソッドを使用すると、すべてのタグを開いたり閉じたり、すべての属性をストリームに追加したりするために、多くのコード行が必要になるようです。結局、必要以上に長いコードになってしまう気がします。

のような連鎖可能なクラスを使用すればStringBuilder、私のコードは読みやすく、書きやすくなると考えていました。

私が疑問に思っていたのは、HtmlTextWriterオブジェクトを使用してコントロール全体のコンテンツをレンダリングする理由はありますか? タグを間違った順序で記述したり、無効なマークアップを作成したりしないようにするための安全チェック (私は推測しています) 以外に、理由がわかりません。

次のようなことをするだけで簡単になるようです:

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

これが悪い考えになる理由はありますか?

更新Mehrdad Afshari
の回答に 応えて:別のオブジェクト をインスタンス化するためのメモリ要件についてはあまり考えていませんでした。余分な文字列が作成されないようにチェーンできるように、HtmlTextWriter のラッパーを作成するのはどうですか。
StringBuilder

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

3 に答える 3

10

私は、開発者があなたが調査している恐ろしい道をたどったアプリケーションに取り組んでいます。これは、HTML コードを吐き出す独自の ISAPI DLL を作成しなければならなかった時代にまでさかのぼります。作業するのは常に頭痛の種です。コードがほとんど文字列である場合、何かが間違っています。

私が変更するこのタイプのコードのほとんどは、サーバー オブジェクトをインスタンス化し、それらのプロパティを必要に応じて構成してから、.RenderControl(writer) に伝えます。これにより、コードが読みやすくなり、操作しやすくなります。これがもたらすオーバーヘッドによってパフォーマンスが低下する場合は、喜んで受け入れます (実際、変更を加えた後、アプリケーションは通常より高速に実行されるため、逸話的にはそうではありませんが、プロファイルは作成していません)。私のコード)。

文字列にハードコーディングすることの単純な欠点の 1 つは、HTML 標準が変更された場合です。私が取り組んでいるコードは 2005 年 4 月に書かれたもので、それ以来 <BR> は <br /> になり、大文字の html タグはコーシャではなくなりました。サーバー コントロールを使用していた場合、それらのサーバー コントロールは何もする必要なくhtmlを出力しました。これは簡単な例の 1 つにすぎません。

編集:ああ、ところで、BeginRender と EndRender には実装がありません。これらは、HtmlTextWriter 派生クラスでオーバーライドしてカスタム機能を提供するためのプレースホルダーです。

EDIT2:コンテナーなどのサーバー コントロールを常に使用するのは少し面倒な場合があります。私は多くの .Controls.Add() を実行してから、後でコンテナーをレンダリングします。だから時々私はこれをします:

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

前述のように、div の html が将来変更された場合でも、これは正しい html をレンダリングします。これは、ハードコードされた文字列がないためです。

于 2009-01-28T22:44:07.230 に答える
4

パフォーマンス面では、これにはより多くの文字列コピーを実行する必要があります。HtmlTextWriter出力バッファに直接書き込みます。StringBuilder一方、独自のバッファがあります。を呼び出すときToStringStringBuilder、新しい文字列を作成する必要があります。その後、。によって出力バッファに書き込まれoutput.Writeます。実行するのにはるかに多くの作業が必要です。

于 2009-01-28T22:32:21.730 に答える
1

私はあなたがBeginRender/EndRenderを呼ぶべきではないと思います、それはページによって行われます。

文字列ビルダーを使用すると、HtmlTextWriters独自のメソッドを使用するよりも作業がどのように節約されるかわかりません。

于 2009-01-28T22:36:29.540 に答える