2012-01-23 10 views
5

¿Es posible determinar si la solicitud actual es una devolución de datos asincrónica (actualización de página parcial) desde el evento Application_Error?Cómo determinar si la solicitud actual es una devolución de datos asincrónica, en el evento Application_Error de ASP.NET

¿Cuál es la mejor forma de manejar los errores de aplicación cuando se utilizan devoluciones de datos asincrónicas?

En Application_Error, estamos redirigiendo a diferentes páginas de error, pero eso no funciona correctamente cuando se produce el error durante una devolución de datos asincrónica. Notamos que esto es cierto incluso cuando AllowCustomErrorsRedirect = false y tenemos un controlador OnAsyncPostBackError para establecer AsyncPostBackErrorMessage. Durante las devoluciones de datos asincrónicas, nuestro AsyncPostBackErrorMessage se sobrescribe y el cliente recibe un error genérico de página web.

+0

http://www.codedigest.com/Articles/ASPNETAJAX/115_Error_Handling_in_ASPNet_Ajax_Applications.aspx –

+0

En este momento ya estamos usando AllowCustomErrorsRedirect = false y la disponibilidad AsyncPostBackErrorMessage. Entonces no veo cómo el artículo es relevante. Pregunta actualizada para incluir el uso del controlador OnAsyncPostBackError. – BlueFox

Respuesta

5

En el método Application_Error ya no tiene acceso directo al control <asp:ScriptManager> en la página. Por lo tanto, es demasiado tarde para manejar su evento AsyncPostBackError.

Si desea evitar un redireccionamiento, debe verificar la solicitud para ver si se trata de una solicitud asincrónica. El <asp:UpdatePanel> provoca un puesto de vuelta con el siguiente encabezado HTTP:

X-MicrosoftAjax:Delta=true 

(véase también: ScriptManager Enables AJAX In Your Web Apps)

Un cheque por esta cabecera podría ser algo como esto:

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 
} 

En cuanto a lo Sería una forma apropiada de manejar la excepción. Es una pregunta diferente.

+0

Tenía miedo de mirar en el encabezado HttpRequest sería la única solución. ¿Qué tan confiable es el encabezado? Además, ¿interferiría esto con las devoluciones de página completa (no asincrónicas)? – BlueFox

+0

El encabezado debe ser bastante confiable, ya que es utilizado por el marco para determinar cómo se debe enviar la respuesta. No debe interferir con las copias de respaldo sincrónicas, el encabezado simplemente no se establecerá o configurará en 'Delta = falso' –

+0

FYI - Este método es creativo y puede ser confiable, pero de hecho es posible acceder al ScriptManager desde Application_Error. Ver mi respuesta para más detalles. – BrianFinkel

1

Tuve una situación similar. Lo que funcionó para mí fue llamar al Server.ClearError() en mi controlador de eventos para el ScriptManager's AsyncPostBackError. Esto evita que se llame a la función Global.asax Application_Error.

0

Dentro de Application_Error, puede acceder a ScriptManager para determinar si la solicitud actual es una devolución de datos asincrónica. El objeto global HttpContext.Current.Handler en realidad apunta a la página que se está revisando, que contiene el objeto ScriptManager, que le dirá si la solicitud actual es asincrónica.

La siguiente declaración concisa ilustra cómo acceder al objeto ScriptManager y obtener esta información:

ScriptManager.GetCurrent(CType(HttpContext.Current.Handler, Page)).IsInAsyncPostBack 

Por supuesto, esta afirmación fallará si la petición actual no es para una página, o si no hay ScriptManager en la página actual, asi que aquí hay un par más robusto de funciones que se pueden utilizar dentro de Global.asax para hacer la determinación:

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 

Sólo tiene que llamar IsInAsyncPostback() desde Application_Error para obtener un valor lógico que indica el estado actual .

Obtiene errores genéricos de ASP.NET en el cliente porque intentar transferir/redirigir una solicitud asíncrona generará más errores, reemplazando y ofuscando el error original. Puede usar el código anterior para evitar la transferencia o redirección en tales casos.

También tenga en cuenta otro descubrimiento que realicé: aunque puede acceder al objeto ScriptManager con este método, por algún motivo, la configuración de su propiedad AsyncPostBackErrorMessage desde Application_Error no funciona. El nuevo valor no se pasa al cliente. Por lo tanto, aún necesitará manejar el evento OnAsyncPostBackError de ScriptManager en la clase de página.

Cuestiones relacionadas