2

ASP.NET アプリケーションで HTML のカスタム レンダリングを行うために、System.Web.UI.HtmlTextWriter を継承しました。これは、次を使用して Web.config ファイルで構成されます。

<browserCaps>
  tagwriter="MyAssembly.CustomHtmlTextWriter, MyAssembly"
</browserCaps>

これは、通常のページ要求に対して正しく機能し、OnTagRender などのオーバーライドされたメソッドが呼び出され、カスタマイズされた HTML がブラウザーに送信されます。

ただし、UpdatePanel を使用して非同期ポストバックを実行すると、このコードは呼び出されず、HTML はカスタム変更なしでブラウザーに到着します。AJAX 要求用にカスタム HtmlTextWriter をロードする構成が不足していますか?

4

1 に答える 1

3

まず、カスタムHTMLTextWriterが正しく呼び出されていること、および構成に問題がないことを確認できます。

web.configセクションを使用して、テストアプリを作成し、次のブレークポイントをvar cap = ...行に含めました。

    protected void UpdatePanel1_Load(object sender, EventArgs e)
    {
        var cap = Request.Browser.TagWriter;
    }

最初のHTTPGETとAJAXポストバックの両方で、ブレークポイントがヒットし、使用されているTagWriterが実際にはCustomHtmlTextWriterであることがわかりました。また、CustomHtmlTextWriterコンストラクターにブレークポイントを設定することもでき、このブレークポイントはポストバックでヒットします。

また、ポストバックに新しいコントロールを追加しても、CustomHtmlTextWriterコンストラクターが呼び出されても、OnTagRender、OnAttributeRender、およびその他のイベントが発生しないことを確認しました。

また、RenderBefore ...()メソッドとRenderAfter ...()メソッドは呼び出されません。

だから、これはあなたの質問に答えます「私は私の構成で何か間違ったことをしていますか?」:いいえ、あなたはそうではありません。カスタムHtmlTextWriterはインスタンス化されて参照されますが、その有用なメソッドは呼び出されません(BeginRenderが呼び出されますが、タグを変更するために通常使用するメソッドは呼び出されません)。

この時点で、browserCapsタグが.NET 2.0で非推奨になっていることに注意してください。したがって、ユースケースがサポートされていないように見えることはおそらく驚くべきことではありません。正確に何をしようとしているかにもよりますが、ControlAdapterアーキテクチャがその仕事を成し遂げるべきだと思います。

たとえば、すべてのTextBoxとLabelをIDを含むスパンのみに置き換え、これを最初のGETとAJAXポストバックで機能させたいとします。確かにあなたの例はもっと複雑になるでしょうが、うまくいけば、この単純化があなたにアイデアを与えるでしょう。

私がする必要があるのは、任意のWebコントロールに作用できるControlAdapterを作成することだけです。

public class CustomControlAdapter : WebControlAdapter
{
    protected override void RenderBeginTag(HtmlTextWriter writer)
    {
        writer.WriteLine();
        writer.WriteBeginTag("span");
        writer.Write(HtmlTextWriter.TagRightChar);
    }

    protected override void RenderEndTag(HtmlTextWriter writer)
    {
        writer.WriteEndTag("/span");
        writer.WriteLine();
    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        writer.WriteLine(Control.ID);
    }
}

次に、作業に関心のある種類のコントロールに接続します。これを行うには、App_BrowsersフォルダーにAdapters.browserファイルを作成し、次の構成を含めます。

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter
        controlType="System.Web.UI.WebControls.Label"
        adapterType="WebApplication1.CustomControlAdapter"
      />
      <adapter
        controlType="System.Web.UI.WebControls.TextBox"
        adapterType="WebApplication1.CustomControlAdapter"
      />
    </controlAdapters>
  </browser>
</browsers>

「デフォルト」のブラウザrefIDは、すべてのブラウザでこれが機能することに注意してください。これで、LabelまたはTextBox Webコントロールをレンダリングする必要がある場合、CustomControlAdapterがそれを処理します。上記のコードは私のサンプルアプリでテストされており、AJAXでも完全に機能します。あなたの場合、上記のAdapters.browserファイルにさらにいくつかのコントロールタイプを追加する必要があると思います。そうすれば、100%ビジネスを行うことができます。

于 2013-02-08T20:11:38.473 に答える