¿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?

Samuel Meacham
fuente

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");
Samuel Meacham
fuente
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.

Philip Rieck
fuente
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.

Mark Cidade
fuente
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.

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

El uso return RedirectPermanent(myUrl)funcionó para mí

Vasilis
fuente
Tengo acción y 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();
Dipanki Jadav
fuente
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.

DucDigital
fuente
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.

Puntilla
fuente
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");}
SamsonOnNet
fuente
1

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

utilsit
fuente
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");

Ram Samuj
fuente
¿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.

Nathan
fuente
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);
Aashish Garg
fuente
0

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

1_bicho
fuente
-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; 
usuario9150083
fuente
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