1

ポップアップ ウィンドウといくつかのクロスページ ポスティングを組み合わせようとすると、恐ろしい例外「UpdatePanel は ScriptManager に登録されていないため、ID 'UpdatePanel' で登録解除できません」という例外が発生します。小さな例で問題を再現できました。

UpdatePanel の Unload イベントを処理する他の質問を見てきましたが、クロス ページ ポスティングの追加では機能しないようです。

この問題を回避するにはどうすればよいですか?

以下のコードで問題を再現するには:

  1. 設定ページを開始する
  2. ポップアップ表示リンクを押します
  3. ポップアップを閉じる
  4. [次へ] ボタンを押して、ターゲット ページに移動します。
  5. [戻る] ボタンを押して、セットアップ ページに移動します。
  6. 表示リンクを押してポップアップを閉じます
  7. [次へ] ボタンを押して、失敗を確認します

ハイライトは次のとおりです (長くなってしまいますが、カット アンド ペースト可能である必要があります)。

セットアップ.aspx

<head runat="server">
    <title>Setup </title>
    <script type="text/javascript">
        function openCenteredWindow(url, height, width, name, parms) {
            //Snip setting up window location stuff
            var win = window.open(url, name, winParms);
            return win;
        }
    </script>
</head>
<body>    
    <h1>Setup Page</h1>
    <form id="aspnetForm" runat="server">
    <div>
        <asp:TextBox ID="txtData" runat="server" Width="80%" Text="<%# Information %>" />
        <br />

        <asp:LinkButton ID="lbViewData" runat="server" 
        OnClientClick="aspnetForm.target='ViewDataPopup';" 
        Text="View In Popup" /> <br />

        <asp:Button ID="btnNext" runat="server" Text="Next" OnClick="btnNext_Click" />
    </div>
    <div>
        <br />
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
    <asp:updatepanel ID="UpdatePanel" runat="server" OnUnload="UpdatePanel_Unload"></asp:updatepanel>
    </div>
    </form>
</body>

Setup.Aspx.cs

public partial class Setup : System.Web.UI.Page
{
    protected override void LoadViewState(object savedState)
    {
        base.LoadViewState(savedState);
        if (this.ViewState["Information"] != null)
            _Information = this.ViewState["Information"].ToString();
    }

    protected override object SaveViewState()
    {
        this.ViewState["Information"] = _Information;
        return base.SaveViewState();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (PreviousPage != null && PreviousPage is TargetPage)
        {
            _Information = ((TargetPage)PreviousPage).SetupData;
        }
        else if (!Page.IsPostBack)
        {
            _Information = String.Format("This test started at {0}", DateTime.Now);
        }
        Page.DataBind();
        lbViewData.PostBackUrl = "ViewData.aspx?u=0";
        lbViewData.Attributes.Add("onclick", "JavaScript:openCenteredWindow(\"ViewData.aspx?u=0\", 400, 300, \"ViewDataPopup\", 'scrollbars=yes');");
    }

    private string _Information;
    public string Information
    {
        get { return _Information; }
    }

    protected void btnNext_Click(object sender, EventArgs e)
    {
        HttpContext.Current.Server.Transfer("~/TargetPage.aspx");
    }
}

ViewData.aspx

<%@ PreviousPageType VirtualPath="~/Setup.aspx" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<head runat="server">
    <title>View Data</title>
       <script type="text/javascript">
           function fixForm() {
               opener.document.getElementById("aspnetForm").target = "";
               opener.document.getElementById("aspnetForm").action = "";               
           }
    </script>
</head>
<body onload="fixForm()">
    <form id="aspnetForm" runat="server">
    <div>
        <h2 >View Data</h2>
    </div>
    <asp:Label ID="lblData" runat="server" Text="<%# SetupData %>" />
    </form>
</body>

ViewData.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    if (PreviousPage != null)
    {
        Setup setup = (Setup)PreviousPage;
        this.SetupData = setup.Information ?? "Data not set in Setup Page";
    }
    Page.DataBind();
}

private string _setupData = "Did not get updated data";
protected string SetupData
{
    get { return _setupData; }
    set { _setupData = value; }
}

TargetPage.aspx

<%@ PreviousPageType VirtualPath="~/Setup.aspx" %>
<body style="background-color: #9999BB">
    <h1>Target Page</h1>
    <form id="aspnetForm" runat="server">
    <div>
        <asp:Label ID="lblData" runat="server" Text="<%# SetupData %>" /><br />
        <asp:Button ID="btnBack" runat="server" Text="Back" OnClick="btnBack_Click" />
    </div>
    </form>
</body>

TargetPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (this.PreviousPage == null)
                Response.Redirect("Setup.aspx");

            this.SetupData = PreviousPage.Information;
        }
        Page.DataBind();
    }

    public string SetupData
    {
        get { return ViewState["SetupData"].ToString(); }
        set { ViewState["SetupData"] = value; }
    }

    protected void btnBack_Click(object sender, EventArgs e)
    {
        HttpContext.Current.Server.Transfer("~/Setup.aspx");
    }

ご覧のとおり、UpdatePanel をページ上に置いておくだけで、このエラーが発生することはありません。

4

0 に答える 0