コントロールアダプタを利用した HTML の書き換え
- id:ladybug:20061113
このあたりで書いた ASP.NET 2.0 の問題を、綺麗に簡単に解決する方法が、どっとねっとふぁんさんのところを読んでいたら ASP.NET 2.0 にあることに気がつきました。
コントロールアダプタを作成してしまえば、HtmlForm の派生クラスも作成しなくてよくて、デザイン画面も開けて、クライアントコールバックも ASP.NET Ajax もできて、PathInfo や QueryString があろうが、URL 書き換えを HttpHandler でやろうが HttpModule でやろうが関係なく、FilePath プロパティがおかしいとかそんな状態にもならない対応ができます。
まず、Form 用のコントロールアダプタを App_Code に作成します。
public class FormActionRewriter : System.Web.UI.Adapters.ControlAdapter { public FormActionRewriter() {} protected override void Render(HtmlTextWriter writer) { base.Render(new Rewriter(writer)); } private class Rewriter : HtmlTextWriter { public Rewriter(HtmlTextWriter writer) : base(writer) { } public override void WriteAttribute(string name, string value, bool fEncode) { if (string.CompareOrdinal(name, "action") == 0) value = HttpContext.Current.Request.RawUrl; base.WriteAttribute(name, value, fEncode); } } }
やってることは、以前と同じです。実装ポイントが HtmlForm の派生クラスではなく ControlAdapter の派生クラスになっただけです。
さらに、App_Browsers フォルダに上記を使用する定義ファイルを作成します。
<browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormActionRewriter" /> </controlAdapters> </browser> </browsers>
これは、すべてのブラウザの HtmlForm のレンダリングに、作成した FormActionRewriter をアダプタとして追加するという設定です。これで、すべての HtmlForm のレンダリングで action 属性が書き換えられ、世界は幸せになります(ぇ?
コントロールアダプタとブラウザ定義ファイルの使い方としてはトリッキーですが、Web アプリは最終的にどのような HTML になるかが勝負ですので、こういったアダプタの使い方を ASP.NET における最終兵器的なアプローチとして知っておくと便利でしょう。