提问人:BlueFox 提问时间:1/24/2012 最后编辑:BrianFinkelBlueFox 更新时间:2/13/2013 访问量:4510
在 ASP.NET Application_Error事件中,如何确定当前请求是否为异步回发
How to determine if current request is an asynchronous postback, in ASP.NET Application_Error event
问:
是否可以从Application_Error事件中确定当前请求是否是异步回发(部分页面更新)?
使用异步回发时处理应用程序错误的最佳方法是什么?
在 Application_Error 中,我们将重定向到不同的错误页面,但是在异步回发期间引发错误时,这将无法正常工作。我们注意到,即使 AllowCustomErrorsRedirect = false,这也成立,并且我们有一个 OnAsyncPostBackError 处理程序来设置 AsyncPostBackErrorMessage。在异步回发期间,我们的 AsyncPostBackErrorMessage 将被覆盖,客户端会收到一个通用网页错误。
答:
在该方法中,您不再能够直接访问页面上的控件。因此,处理其 AsyncPostBackError 事件为时已晚。Application_Error
<asp:ScriptManager>
如果要阻止重定向,则应检查请求以查看它是否实际上是异步请求。这会导致回发,并显示以下 HTTP 标头:<asp:UpdatePanel>
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
}
至于处理异常的适当方法是另一个问题,恕我直言。
评论
Delta=false
我也有类似的情况。对我有用的是调用我的事件处理程序来调用 ScriptManager 的 .这样可以防止调用 Global.asax 函数。Server.ClearError()
AsyncPostBackError
Application_Error
在 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 事件。
评论