7

是否可以从 Application_Error 事件中确定当前请求是否是异步回发(部分页面更新)?

使用异步回发时处理应用程序错误的最佳方法是什么?

在 Application_Error 中,我们重定向到不同的错误页面,但是在异步回发期间抛出错误时,这将无法正常工作。我们注意到,即使 AllowCustomErrorsRedirect = false 并且我们有一个 OnAsyncPostBackError 处理程序来设置 AsyncPostBackErrorMessage,这仍然成立。在异步回发期间,我们的 AsyncPostBackErrorMessage 被覆盖,客户端收到一个通用的网页错误。

4

3 回答 3

8

在该Application_Error方法中,您不再可以直接访问<asp:ScriptManager>页面上的控件。所以现在处理它的AsyncPostBackError事件为时已晚。

如果要防止重定向,则应检查请求以查看它是否实际上是异步请求。<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 回答