在 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 事件。