是否可以从Application_Error事件中确定当前请求是否是异步回发(部分页面更新)?
使用异步回发时处理应用程序错误的最佳方法是什么?
在Application_Error中,我们将重定向到不同的错误页面,但在异步回发期间抛出错误时,该方法无法正常工作。我们注意到,即使AllowCustomErrorsRedirect = false,我们也有一个OnAsyncPostBackError处理程序来设置AsyncPostBackErrorMessage。在异步回发期间,我们的AsyncPostBackErrorMessage被覆盖,客户端会收到一般网页错误。
答案 0 :(得分:6)
在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。
答案 1 :(得分:1)
我有类似的情况。对我有用的是在我的事件处理程序中为ScriptManager的Server.ClearError()
调用AsyncPostBackError
。这样可以防止调用Global.asax Application_Error
函数。
答案 2 :(得分: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事件。