今日電子メールを受け取り、UpdatePanel を UrlRewrite と組み合わせると問題が発生する理由を尋ねられました。以前に UrlRewrite で UpdatePanel も使用したことがあったため、最初は真剣に考えていませんでしたが、問題はありませんでした。しかし、先方からパッケージ化されたコードを受け取った後、対象のページに直接アクセスすると問題が再発することがわかりました。当時私は会社にいたので、エラーの原因を詳しく調べていなかったからだ。帰り道、UpdatePanelの実装プロセスを何度も頭の中でシミュレーションしましたが、何もおかしいところはありませんでした。結局、私はどうすることもできず、バスに乗りながらノートパソコンを開いて、問題を注意深く探しました。バスはかなり揺れましたが、幸いにも嘔吐する前に問題を発見できました。
問題の再現:
次に、問題を再現します。元のコードでは NBear の UrlRewriteModule が使用されていましたが、NBear に詳しくない友人 (私を含む) が記事の理解を妨げないようにするために、最も一般的な UrlRewrite メソッドを使用しました。コンテンツ。
まず、新しい ASP.NET AJAX 対応 Web サイトを作成します。次の内容のファイル ~/SubFolder/Target.aspx を作成します:
~/SubFolder/Target.aspx
<html xmlns=" http://www.w3.org/1999/xhtml " >
<head runat="サーバー">
<title>ターゲットページ</title>
</head>
<本文>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:スクリプトマネージャー>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<コンテンツテンプレート>
<%= DateTime.Now.ToString() %>
<asp:Button ID="Button1" runat="server" Text="更新" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
次に、次のように、Global.asax を作成し、Application_BeginRequest メソッドを提供し、それに URL Rewrite を実装します。
Global.asax の Application_BeginRequest メソッド
void Application_BeginRequest(オブジェクト送信者、EventArgs e)
{
HttpContext context = (HttpApplication として送信).Context;
if (context.Request.Path.Contains("Source.aspx"))
{
context.RewritePath("SubFolder/Target.aspx", false);
}
}
このようにして、~/Source.aspx ファイルにアクセスすると、ファイルは ~/SubFolder/Target.aspx に書き換えられ、ページを開くと、すべてが正常になります。
「更新」ボタンをクリックすると時刻が更新されます。次に、もう一度ボタンをクリックすると、「Sys.WebForms.PageRequestManagerServerErrorException: サーバーでの要求の処理中に不明なエラーが発生しました。サーバーから返されたステータス コードは: 12031」というエラーが発生しました。
問題の分析:
この問題の理由は、URL Rewrite がフォームによって送信されたアドレスを更新し、UpdatePanel がアドレスの変更をページに反映することです。
初めてページを開いたとき、ページのソース ファイル内の <form /> 要素のアクションが、アクセスした Source.aspx ではなく、URL 書き換え後のターゲット ファイルであることがわかります
。 form要素の部分が対象ページです
...
<form name="form1" method="post" action="SubFolder/Target.aspx" id="form1">
...
</form>
...
幸いなことに、「ターゲット」が正しい限り、UpdatePanel はデータを正しく送信および取得し、ページを更新できます。したがって、「更新」ボタンをクリックすると、ページは正しく更新されます。ただし、フォーム要素のアクションも変更されており、Web 開発ヘルパーと IE 開発ツールバーを使用すると一目でわかります。
非同期 PostBack を実行するときに ~/SubFolder/Target.aspx に直接アクセスしたため、生成された Form オブジェクトのアクション値は Target.aspx になります。その結果、UpdatePanel はクライアント フォーム要素のアクションを熱心に変更しました。これにより、再送信するときに存在しないページにアクセスできるようになり、エラーが避けられなくなります。
問題を解決する:
問題を発見したら、当然、簡単に解決できるようになります。 Sys.Application の読み込みイベントに応答するだけで済みます。このイベントは、ページが初めて読み込まれるときと、各部分レンダリング後にトリガーされます。この時点で、ページ内のフォーム要素の action 属性を変更できます。 、次のように:
対応する Sys.Application ロード イベント
Sys.Application.add_load(関数()
{
var form = Sys.WebForms.PageRequestManager.getInstance()._form;
form._initialAction = form.action = window.location.href;
});
なぜこのようにしてページ内のform要素を取得する必要があるのか、_initialActionとは何か、なぜ設定する必要があるのかについては、UpdatePanelの実装に関わるため、ここでは説明しません。このような小さなコードがページ上に配置されている限り、この問題は解決されます。
詳細な質問:
この問題の理由は、実際には、URL 書き換え後のフォーム要素のアクションが、クライアントによって要求されたアドレスではなく、URL 書き換えのターゲット アドレスであることです。部分レンダリングを使用せずに最も伝統的な PostBack を使用すると、ページ機能は損なわれませんが、PostBack 後、ユーザーはアドレス バーの内容が変更され、直接ターゲット アドレスになることに気づくでしょう。これは私たちが望んでいる結果ではありません。書き直したので、最後まで書き直してみましょう。もちろん、上記の方法を引き続き使用し、JavaScript を使用してフォーム要素のアクションを変更することはできますが、この方法は十分に「美しく」はなく、ユーザーは HTML ソースから URL リライトのターゲット アドレスを確認することもできます。ファイルではなく?
フォームのアクションをサーバー側で設定できれば素晴らしいのですが、残念ながら System.Web.UI.HtmlControls.HtmlForm クラスではこれを行うことができません。しかし幸いなことに、私たちは ASP.NET を使用しており、オブジェクト指向プログラミング モデルを使用しています。したがって、System.Web.UI.HtmlControls.HtmlForm を「継承」し、独自の Form コントロールを実装します。HtmlForm
クラスを継承して独自の From を実装します。
名前空間 ActionlessForm {
パブリック クラス フォーム : System.Web.UI.HtmlControls.HtmlForm
{
protected オーバーライド void RenderAttributes(HtmlTextWriter ライター)
{
Writer.WriteAttribute("名前", this.Name);
Base.Attributes.Remove("名前");
Writer.WriteAttribute("メソッド", this.Method);
Base.Attributes.Remove("メソッド");
this.Attributes.Render(ライター);
Base.Attributes.Remove("アクション");
if (base.ID != null)
Writer.WriteAttribute("id", Base.ClientID);
}
}
}
その後、ページ内で使用できるようになります。もちろん、その前に、ページ (または Web.config) に登録する必要があります。
独自に実装されたフォームを使用します。
<%@ 登録 TagPrefix="skm" 名前空間="ActionlessForm"
アセンブリ="アクションレスフォーム" %>
...
<skm:Form id="Form1" Method="post" runat="server">
...
</skm:フォーム>
...
この時点で、ページ内に「賢い」JavaScript を記述する必要はなくなりました。URL 書き換え後のフォーム要素のアクションの問題は解決されました。
(「詳細な質問」とは、MSDN の以前の記事の一部を指します: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp )
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/27/updatepanel_with_url_rewrite.html