7

Application_Error イベント内から、現在のリクエストが非同期ポストバック (部分的なページ更新) であるかどうかを判断することはできますか?

非同期ポストバックが使用されている場合にアプリケーション エラーを処理する最善の方法は何ですか?

Application_Error では、別のエラー ページにリダイレクトしていますが、非同期ポストバック中にエラーがスローされると、正しく動作しません。これは、AllowCustomErrorsRedirect = false の場合でも当てはまり、AsyncPostBackErrorMessage を設定する OnAsyncPostBackError ハンドラーがあることに気付きました。非同期ポストバック中に、AsyncPostBackErrorMessage が上書きされ、クライアントは代わりに一般的な Web ページ エラーを受け取ります。

4

3 に答える 3

8

メソッドでは、ページ上Application_Errorのコントロールに直接アクセスできなくなりました。そのため、 AsyncPostBackErrorイベント<asp:ScriptManager>を処理するには遅すぎます。

リダイレクトを防ぎたい場合は、リクエストをチェックして、それが実際に非同期リクエストであるかどうかを確認する必要があります。これ<asp:UpdatePanel>により、次の HTTP ヘッダーでポスト バックが発生します。

X-MicrosoftAjax:Delta=true

(参照: ScriptManager は Web アプリで AJAX を有効にします)

このヘッダーのチェックは次のようになります。

HttpRequest request = HttpContext.Current.Request;
string header = request.Headers["X-MicrosoftAjax"];
if(header != null && header == "Delta=true") 
{
  // This is an async postback
}
else
{
  // Regular request
}

例外を処理する適切な方法については、別の質問です。

于 2012-01-23T21:56:15.513 に答える
1

同様のシナリオがありました。私にとってうまくいったServer.ClearError()のは、ScriptManager のAsyncPostBackError. これにより、Global.asaxApplication_Error関数が呼び出されなくなります。

于 2012-06-28T22:05:06.107 に答える
0

Application_Error 内で、実際に ScriptManager にアクセスして、現在のリクエストが非同期ポストバックかどうかを判断できます。グローバル オブジェクト HttpContext.Current.Handler は、実際にはサービス対象のページを指しています。このページには、現在の要求が非同期かどうかを示す ScriptManager オブジェクトが含まれています。

次のステートメントは、ScriptManager オブジェクトにアクセスしてこの情報を取得する方法を簡潔に示しています。

ScriptManager.GetCurrent(CType(HttpContext.Current.Handler, Page)).IsInAsyncPostBack

もちろん、現在の要求がページに対するものでない場合、または現在のページに ScriptManager がない場合、そのステートメントは失敗します。そのため、Global.asax 内で使用して判断を下すことができる、より堅牢な関数のペアを次に示します。

Private Function GetCurrentScriptManager() As ScriptManager
    'Attempts to get the script manager for the current page, if there is one

    'Return nothing if the current request is not for a page
    If Not TypeOf HttpContext.Current.Handler Is Page Then Return Nothing

    'Get page
    Dim p As Page = CType(HttpContext.Current.Handler, Page)

    'Get ScriptManager (if there is one)
    Dim sm As ScriptManager = ScriptManager.GetCurrent(p)

    'Return the script manager (or nothing)
    Return sm
End Function

Private Function IsInAsyncPostback() As Boolean
    'Returns true if we are currently in an async postback to a page

    'Get current ScriptManager, if there is one
    Dim sm As ScriptManager = GetCurrentScriptManager()

    'Return false if no ScriptManager
    If sm Is Nothing Then Return False

    'Otherwise, use value from ScriptManager
    Return sm.IsInAsyncPostBack
End Function

Application_Error 内から IsInAsyncPostback() を呼び出すだけで、現在の状態を示すブール値を取得できます。

非同期要求を転送/リダイレクトしようとすると、より多くのエラーが生成され、元のエラーが置き換えられて難読化されるため、クライアントで一般的な ASP.NET エラーが発生しています。上記のコードを使用して、そのような場合の転送またはリダイレクトを防ぐことができます。

また、私が行った別の発見にも注意してください。このメソッドを使用して ScriptManager オブジェクトにアクセスできますが、何らかの理由で、Application_Error 内から AsyncPostBackErrorMessage プロパティを設定しても機能しません。新しい値はクライアントに渡されません。したがって、ページ クラスで ScriptManager の OnAsyncPostBackError イベントを処理する必要があります。

于 2013-02-13T15:47:26.130 に答える