¿Por qué obtengo el mensaje "No se puede redireccionar después de que se hayan enviado los encabezados HTTP" cuando llamo a Response.Redirect ()?


84

Cuando llamo Response.Redirect(someUrl), obtengo la siguiente HttpException:

No se puede redireccionar después de que se hayan enviado los encabezados HTTP.

¿Por qué obtengo esto? ¿Y cómo puedo solucionar este problema?

Respuestas:


120

De acuerdo con la documentación de MSDN Response.Redirect(string url), lanzará una HttpException cuando "se intente una redirección después de que se hayan enviado los encabezados HTTP". Dado que Response.Redirect(string url)utiliza el encabezado de respuesta Http "Location" ( http://en.wikipedia.org/wiki/HTTP_headers#Responses ), llamarlo hará que los encabezados se envíen al cliente. Esto significa que si lo llama por segunda vez, o si lo llama después de haber hecho que los encabezados se envíen de alguna otra manera, obtendrá la HttpException.

Una forma de evitar llamar a Response.Redirect () varias veces es comprobar la Response.IsRequestBeingRedirectedpropiedad (bool) antes de llamarla.

// Causes headers to be sent to the client (Http "Location" response header)
Response.Redirect("http://www.stackoverflow.com");
if (!Response.IsRequestBeingRedirected)
    // Will not be called
    Response.Redirect("http://www.google.com");

2
Sí, exactamente. Esto sucede con bastante facilidad con ASP.NET MVC 4 y los filtros de excepción, etc. Tampoco puede cambiar el código de estado de respuesta HTTP una vez que se ha emitido una redirección 301/302.
Jaans

Resolví el problema haciendo que todas las propiedades en mi página fueran 'estáticas'
Sal

4
hacer que sus propiedades sean estáticas es una solución peligrosa
prospector

¿Cómo se puede llamar a la redirección por segunda vez a menos que se detecte la excepción ThreadAbortException (de la primera vez)? :} "Llamar a Redirect es equivalente a llamar a Redirect con el segundo parámetro ( endResponse) establecido en verdadero".
user2864740

1
Es extraño, pero en una aplicación de formularios web heredados Response.IsRequestBeingRedirectedes falso y sigo recibiendo esta misma excepción ( Application_EndRequestmétodo de evento interno en Global.asax). No puedo entender por qué.
Alisson

17

Una vez que envíe cualquier contenido al cliente, los encabezados HTTP ya se enviaron. Una Response.Redirect()llamada funciona enviando información especial en los encabezados que hacen que el navegador solicite una URL diferente.

Dado que los encabezados ya se enviaron, asp.net no puede hacer lo que desea (modificar los encabezados)

Puede evitar esto a) haciendo el redireccionamiento antes de hacer cualquier otra cosa, ob) intente usarlo Response.Buffer = trueantes de hacer cualquier otra cosa, para asegurarse de que no se envíe ningún resultado al cliente hasta que toda la página haya terminado de ejecutarse.


Para mi no funciona. Utilizo .NET, MVC y tengo una llamada dentro del método del controlador. Sigo recibiendo una excepción, aunque ocurre la redirección.
FrenkyB

8

Una redirección solo puede ocurrir si la primera línea de un mensaje HTTP es " HTTP/1.x 3xx Redirect Reason".

Si ya llamó Response.Write()o estableció algunos encabezados, será demasiado tarde para una redirección. Puede intentar llamar Response.Headers.Clear()antes de la redirección para ver si eso ayuda.


Yo uso return RedirectToAction("Logout", "Authentication");y me sale ese error
Kiquenet

Cuando intenté borrar los encabezados, obtuve System.PlatformNotSupportedException: esta operación requiere el modo de canalización integrado de IIS.
Irish Chieftain

3

Simplemente verifique si ha establecido la opción de almacenamiento en búfer en falso (por defecto es verdadero). Para que response.redirect funcione,

  1. El almacenamiento en búfer debe ser cierto,
  2. no debería haber enviado más datos usando response.write, que excede el tamaño de búfer predeterminado (en cuyo caso se vaciará y hará que se envíen los encabezados), por lo que no le permitirá redireccionar.

1
Response.BufferOutput = true;en la acción, en el controlador?
Kiquenet


2

También puede usar el código mencionado a continuación

Response.Write("<script type='text/javascript'>"); Response.Write("window.location = '" + redirect url + "'</script>");Response.Flush();

1

Hay una respuesta simple para esto: ha generado algo más, como texto, o cualquier cosa relacionada con la salida de su página antes de enviar su encabezado. Esto afecta la razón por la que obtiene ese error.

Simplemente verifique su código para una posible salida o puede colocar el encabezado en la parte superior de su método para que se envíe primero.


1

Si está intentando redirigir después de que se hayan enviado los encabezados (si, por ejemplo, está haciendo una redirección de error desde una página generada parcialmente), puede enviar algún cliente Javascript (location.replace o location.href, etc.) para redirigir a la URL que desee. Por supuesto, eso depende de qué HTML ya se haya enviado.


1

Mi problema se resolvió agregando el controlador de excepciones para manejar "No se puede redireccionar después de que se hayan enviado los encabezados HTTP". este error como se muestra a continuación código

catch (System.Threading.ThreadAbortException)
        {
            // To Handle HTTP Exception "Cannot redirect after HTTP headers have been sent".
        }
        catch (Exception e)
        {//Here you can put your context.response.redirect("page.aspx");}

1

Resolví el problema usando: Response.RedirectToRoute ("CultureEnabled", RouteData.Values); en lugar de Response.Redirect.


1

Error No se puede redireccionar después de que se hayan enviado los encabezados HTTP.

System.Web.HttpException (0x80004005): no se puede redireccionar después de que se hayan enviado los encabezados HTTP.

Sugerencia

Si usamos asp.net mvc y trabajamos en el mismo controlador y redirigimos a una acción diferente, no es necesario que escriba ..
Response.Redirect ("ActionName", "ControllerName");
es mejor usar solo
return RedirectToAction ("ActionName");
o
devolver View ("ViewName");


¿Uso ActionName de otro ControllerName?
Kiquenet

0

La función de redireccionamiento probablemente funcione usando el encabezado http 'actualizar' (y tal vez usando un código 30X también). Una vez que los encabezados se han enviado al cliente, no hay forma de que el servidor agregue ese comando de redireccionamiento, es demasiado tarde.


0

Si obtiene No se puede redireccionar después de que se hayan enviado los encabezados HTTP, intente con el siguiente código.

HttpContext.Current.Server.ClearError();
// Response.Headers.Clear();
HttpContext.Current.Response.Redirect("/Home/Login",false);

0

Asegúrese de no utilizar Responselos métodos de s como Response.Flush();antes de la parte de redireccionamiento.


-3

Hay dos formas de solucionar este problema:

  1. Simplemente agregue una returndeclaración después de su Response.Redirect(someUrl); (si la firma del método no es "nula", tendrá que devolver ese "tipo", por supuesto) así:

    Response.Redirect ("Login.aspx");

    regreso;

Tenga en cuenta que la devolución permite que el servidor realice la redirección ... sin ella, el servidor quiere continuar ejecutando el resto de su código ...

  1. Haga su Response.Redirect(someUrl)ÚLTIMA instrucción ejecutada en el método que está lanzando la excepción. Reemplace su Response.Redirect(someUrl)con una cadena VARIABLE llamada "someUrl", y configúrela en la ubicación de redireccionamiento ... de la siguiente manera:

//......some code

string someUrl = String.Empty

..... algo de lógica

if (x=y)
{
    // comment (original location of Response.Redirect("Login.aspx");)
    someUrl = "Login.aspx";
}

...... más código

// MUEVA su Response.Redirect a AQUÍ (el final del método):

Response.Redirect(someUrl);
return; 

lo siento, pero esto no tiene ningún sentido para mí. ¿Qué debería hacer (en un método de devolución de vacío) ese redundante return? El returnúnico define que el método está completo. Pero cuando no queda ningún código, el método se completa de todos modos. Y almacenar una URL en una variable no cambia nada, quiero decir: ¿por qué debería hacerlo? La cuerda es la misma. Lo compilado no hace ninguna diferencia entre una cadena y una variable que contiene una cadena ...: piense x = 5, entonces x es 5 pero 5 también es 5. incluso 10/2 sería 5 ... tampoco hay diferencia
Matthias Burger
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.