2012-01-23 12 views
5

現在のリクエストがApplication_Errorイベント内からの非同期ポストバック(部分ページ更新)であるかどうかを判別できますか?ASP.NET Application_Errorイベントで現在のリクエストが非同期ポストバックかどうかを判断する方法

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

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

+0

http://www.codedigest.com/Articles/ASPNETAJAX/115_Error_Handling_in_ASPNet_Ajax_Applications.aspx –

+0

申し訳ありませんが、既にAllowCustomErrorsRedirect = falseを使用しており、AsyncPostBackErrorMessageを提供しています。だから私は記事がどのように関連しているかはわかりません。 OnAsyncPostBackErrorハンドラの使用を含む質問が更新されました。 – BlueFox

答えて

5

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

リダイレクトを防止する場合は、実際に非同期要求かどうかを確認する必要があります。 <asp:UpdatePanel>は、以下のHTTPヘッダでポストバックが発生します。

X-MicrosoftAjax:Delta=true 

(参照:ScriptManager Enables AJAX In Your Web Apps

をこのヘッダのチェックはこのようなものになりますものにしたよう

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 
} 

を例外を処理する適切な方法は、別の質問imhoだろう。

+0

私はHttpRequestヘッダーを調べることが唯一の解決策であることを恐れていました。ヘッダーの信頼性はどれくらいですか?また、これはフルページ(none-async)ポストバックを妨げるでしょうか? – BlueFox

+0

ヘッダーはフレームワークが応答の送信方法を決定するために使用するので、信頼性が高いはずです。これは、同期ポストバックを妨げるべきではなく、ヘッダーは単に設定されないか、または「Delta = false」に設定されます。 –

+0

FYI - このメソッドは創造的で信頼性がありますが、実際はApplication_Error内からScriptManagerにアクセスできます。詳細は私の答えを見てください。 – BrianFinkel

1

私は同様のシナリオを持っていました。私のために働いたのはScriptManagerのAsyncPostBackErrorのイベントハンドラでServer.ClearError()と呼んでいました。これにより、Global.asax Application_Error関数が呼び出されなくなります。

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イベントを処理する必要があります。

関連する問題