Saltar al contenido

¿Por qué Response.Redirect provoca System.Threading.ThreadAbortException?

Si encuentras algún fallo con tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al proyecto final.

Solución:

El patrón correcto es llamar a la sobrecarga de redirección con endResponse=false y haga una llamada para decirle a la canalización de IIS que debe avanzar directamente a la etapa EndRequest una vez que devuelva el control:

Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();

Esta publicación de blog de Thomas Marquardt proporciona detalles adicionales, incluido cómo manejar el caso especial de redirección dentro de un controlador Application_Error.

Hay no solución simple y elegante a la Redirect problema en ASP.Net WebForms. Puedes elegir entre el Sucio solución y la Tedioso solución

Sucio: Response.Redirect(url) envía una redirección al navegador y luego lanza un ThreadAbortedException para terminar el hilo actual. Por lo tanto, no se ejecuta ningún código más allá de la llamada Redirect(). Desventajas: es una mala práctica y tiene implicaciones de rendimiento para matar hilos como este. También, ThreadAbortedExceptions aparecerá en el registro de excepciones.

Tedioso: La forma recomendada es llamar Response.Redirect(url, false) y luego Context.ApplicationInstance.CompleteRequest() Sin embargo, la ejecución del código continuará y el resto de los controladores de eventos del ciclo de vida de la página seguirán ejecutándose. (Por ejemplo, si realiza la redirección en Page_Load, no solo se ejecutará el resto del controlador, sino que también se llamará a Page_PreRender, etc.; la página procesada simplemente no se enviará al navegador. Puede evitar el procesamiento adicional al por ejemplo, establecer un indicador en la página y luego permitir que los controladores de eventos subsiguientes verifiquen este indicador antes de realizar cualquier procesamiento.

(La documentación a CompleteRequest afirma que “Hace que ASP.NET omita todos los eventos y el filtrado en la cadena de ejecución de la canalización HTTP“. Esto puede malinterpretarse fácilmente. Omite más filtros y módulos HTTP, pero no omite más eventos en el actual página ciclo vital.)

El problema más profundo es que WebForms carece de un nivel de abstracción. Cuando está en un controlador de eventos, ya está en el proceso de crear una página para la salida. Redirigir en un controlador de eventos es feo porque está terminando una página generada parcialmente para generar una página diferente. MVC no tiene este problema ya que el flujo de control está separado de las vistas de representación, por lo que puede hacer una redirección limpia simplemente devolviendo un RedirectAction en el controlador, sin generar una vista.

Sé que llego tarde, pero solo he tenido este error si mi Response.Redirect está en un Try...Catch cuadra.

Nunca coloques un Response.Redirect en un bloque Try…Catch. es una mala practica

Como alternativa a colocar Response.Redirect en el bloque Try…Catch, dividiría el método/función en dos pasos.

  1. dentro del bloque Try…Catch realiza las acciones solicitadas y establece un valor de “resultado” para indicar el éxito o el fracaso de las acciones.

  2. fuera del bloque Try…Catch hace la redirección (o no) dependiendo de cuál sea el valor del “resultado”.

Este código está lejos de ser perfecto y probablemente no debería copiarse ya que no lo he probado..

public void btnLogin_Click(UserLoginViewModel model)

    bool ValidLogin = false; // this is our "result value"
    try
    
        using (Context Db = new Context)
        
            User User = new User();

            if (String.IsNullOrEmpty(model.EmailAddress))
                ValidLogin = false; // no email address was entered
            else
                User = Db.FirstOrDefault(x => x.EmailAddress == model.EmailAddress);

            if (User != null && User.PasswordHash == Hashing.CreateHash(model.Password))
                ValidLogin = true; // login succeeded
        
    
    catch (Exception ex)
    
        throw ex; // something went wrong so throw an error
    

    if (ValidLogin)
    
        GenerateCookie(User);
        Response.Redirect("~/Members/Default.aspx");
    
    else
    
        // do something to indicate that the login failed.
    

Si te sientes motivado, tienes el poder dejar un post acerca de qué le añadirías a este artículo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *