如何在ASP.NET Application_Error事件中确定当前请求是否是异步回发

时间:2012-01-23 20:29:13

标签: asp.net asyncpostbackerror

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

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

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

3 个答案:

答案 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事件。