2

私は過去数週間、多くのインフラストラクチャを備えたかなり古いアプリケーションの多数の欠陥を見つけ出そうとしています。私が持っている時間枠で修正することはおそらく期待できない複数のサードパーティのコントロールを使用しています. これらの欠陥の 1 つは、クライアント状態の複数の JavaScript モデルに帰着します。具体的には、jQuery フォーム送信イベントにフックできることを期待するコントロールもあれば、生の .NET で動作するもの (theForm.onsubmit直接1をオーバーライドする) もあれば、 (一部のページで)Sys.WebFormsイベント ハンドラーを使用して登録するコントロールもあります。PageRequestManager

最初は、単に新しい関数をページに追加できると思っていましたが、標準関数とインターセプトするため__doPostBackに実行されるコードとの間で実行するために (時々) 挿入することができません。後でオーバーライドすると、WebForms 内部のロジックをトリガーできないか、jQuery イベントをトリガーできません。元の機能の前に挿入することはできますが、元の機能がページに追加されないようにしないと何もしません。そこで、次のコードを思いつきました。Sys.WebForms__doPostBack__doPostBack

これが私が実際に試みていることを行う唯一の方法である場合、オンラインでまだ見つけていないのはなぜですか? これを行うより良い方法はありますか?

public class Form : System.Web.UI.HtmlControls.HtmlForm 
{
    const string DoPostBackFn = @"
    <script type=""text/javascript"">
    (function ($) {
        window.theForm = document.forms[0];
        window.__doPostBack = function (eventTarget, eventArgument) {
            var originalvalues = [
                theForm.__EVENTTARGET.value,
                theForm.__EVENTARGUMENT.value,
                theForm.onsubmit
            ];
            if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
                theForm.__EVENTTARGET.value = eventTarget;
                theForm.__EVENTARGUMENT.value = eventArgument;
                try {
                    theForm.onsubmit = null;
                    $(theForm).submit();
                } finally {
                    theForm.__EVENTTARGET.value = originalvalues[0];
                    theForm.__EVENTARGUMENT.value = originalvalues[1];
                    theForm.onsubmit = originalvalues[2];
                }
            }
        };
    }(jQuery));
    </script>";

    protected override void RenderChildren(HtmlTextWriter writer) 
    {
        //temporarily disable the page from rendering the postback script
        var fRequirePostBackScript = typeof(System.Web.UI.Page).GetField("_fRequirePostBackScript", BindingFlags.Instance | BindingFlags.NonPublic);
        var isPostBackRequired = (bool)fRequirePostBackScript.GetValue(Page);
        if (isPostBackRequired) 
        {
            fRequirePostBackScript.SetValue(Page, false);

            //write custom postback script
            writer.Write(DoPostBackFn);
            //tell the page that the script is rendered already
            typeof(System.Web.UI.Page).GetField("_fPostBackScriptRendered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(Page, true);
        }

        //let ASP.NET do its thing
        base.RenderChildren(writer);

        //reset field to original value
        fRequirePostBackScript.SetValue(Page, isPostBackRequired);
    }
}

1Sys.WebFormsこれは、既に登録されているものに関係なく (少なくともこのバージョンでは) DOM イベントを盲目的に上書きするため、 がページ上にあるときには明らかにできないことです。

4

0 に答える 0