ASP.NETにおけるformタグのaction属性書換

ASP.NETにおけるformタグのaction属性を書き換える方法を書いてみます。

formタグのaction属性を直接aspxファイルに記述しても、
実行時に上書きされてしまいます。
ポストバック時にページ内リンク(例/index.asp#main)を使用したい場合など、
この仕様だと不都合が生じることがあります。

そこで、HtmlTextWriterクラスのサブクラスを作成し、
そのクラス内でaction属性を書き換えます。

public class MyWriter : HtmlTextWriter
{
    private TextWriter writer;
    private string anchor;

    /// <summary>
    /// formタグのaction属性に設定される値です。
    /// </summary>
    public string Anchor
    {
        get { return this.anchor; }
        set { this.anchor = value; }
    }
    
    public MyWriter(TextWriter writer) 
        : base(writer)
    {
        this.writer = writer;
    }
    
    public MyWriter(TextWriter writer, string tabString) 
        : base(writer, tabString)
    {
        this.writer = writer;
    }
    
    public override void WriteAttribute(string name, string value, bool fEncode)
    {
        if (string.Compare(name, "action", true) == 0)
        {
            // ここでaction属性値を書換
            value = this.anchor == null ? "" : this.anchor;
        }
        base.WriteAttribute(name, value, fEncode);
    }
}

引用元:How to render form tag with action="" - uber1024's WebLog
http://weblogs.asp.net/uber1024/archive/2004/04/08/109720.aspx

引用元では、formタグ検出時の処理もカスタム出来るように
RenderBeginTagメソッドをオーバーライドしていますが、
単なるaction属性の書き換えの場合は必要ないと思われるので省略しました。

上記コードでは、Anchorプロパティの値をaction属性として扱います。
そのため、WriteAttributeメソッドが実行される前に、
Anchorプロパティに値を設定する必要があります。

最後に、ページ本体でRenderメソッドをオーバーライドし、
上記MyWriterクラスを利用してaction属性を書き換える処理を記述します。

public partial class _Default : Page
{
    private MyWriter myWriter;

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected override void Render(HtmlTextWriter writer)
    {
        if (this.myWriter == null)
        {
            this.myWriter = new MyWriter(writer);
            this.myWriter.Anchor = "index.aspx#main";
        }
        base.Render(this.mywriter);
    }
}

こんな感じでしょうか。