Warum wird beim Aufrufen von Response.Redirect () die Meldung "Kann nach dem Senden von HTTP-Headern nicht umgeleitet werden" angezeigt?

83

Wenn ich Response.Redirect(someUrl)anrufe, erhalte ich die folgende HttpException:

Kann nicht umleiten, nachdem HTTP-Header gesendet wurden.

Warum bekomme ich das? Und wie kann ich dieses Problem beheben?

Samuel Meacham
quelle

Antworten:

119

Gemäß der MSDN-Dokumentation für Response.Redirect(string url)wird eine HttpException ausgelöst, wenn "eine Umleitung versucht wird, nachdem die HTTP-Header gesendet wurden". Da Response.Redirect(string url)der HTTP-Antwortheader "Location" ( http://en.wikipedia.org/wiki/HTTP_headers#Responses ) verwendet wird, werden die Header beim Aufrufen an den Client gesendet. Dies bedeutet, dass Sie die HttpException erhalten, wenn Sie es ein zweites Mal aufrufen oder wenn Sie es aufrufen, nachdem Sie die Header auf andere Weise gesendet haben.

Eine Möglichkeit, sich vor dem mehrmaligen Aufrufen von Response.Redirect () zu schützen, besteht darin, die Response.IsRequestBeingRedirectedEigenschaft (bool) vor dem Aufruf zu überprüfen .

// 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
quelle
2
Ja genau. Dies ist mit ASP.NET MVC 4 und den Ausnahmefiltern usw. recht einfach. Sie können den HTTP-Antwortstatuscode auch nicht ändern, sobald eine Umleitung 301/302 ausgegeben wurde.
Jaans
Ich habe das Problem gelöst, indem ich alle Eigenschaften auf meiner Seite 'statisch' gemacht habe
Sal
4
Ihre Eigenschaften statisch zu machen ist eine gefährliche Lösung
Prospektor
Wie kann die Umleitung ein zweites Mal aufgerufen werden, wenn die ThreadAbortException (vom ersten Mal) nicht abgefangen wird? :} "Das Aufrufen von Redirect entspricht dem Aufrufen von Redirect, wobei der zweite Parameter ( endResponse) auf true gesetzt ist."
user2864740
1
Es ist seltsam, aber in einer älteren Webforms-Anwendung Response.IsRequestBeingRedirectedist es falsch und ich erhalte immer noch dieselbe Ausnahme (innerhalb der Application_EndRequestEreignismethode in Global.asax). Ich kann nicht verstehen warum.
Alisson
17

Sobald Sie Inhalte an den Client gesendet haben, wurden die HTTP-Header bereits gesendet. Ein Response.Redirect()Anruf sendet spezielle Informationen in den Kopfzeilen, die den Browser dazu veranlassen, nach einer anderen URL zu fragen.

Da die Header bereits gesendet wurden, kann asp.net nicht das tun, was Sie wollen (ändern Sie die Header).

Sie können dies umgehen, indem Sie a) entweder die Umleitung Response.Buffer = trueausführen , bevor Sie etwas anderes tun, oder b) versuchen, sie zu verwenden, bevor Sie etwas anderes tun, um sicherzustellen, dass keine Ausgabe an den Client gesendet wird, bis die gesamte Seite ausgeführt ist.

Philip Rieck
quelle
Bei mir funktioniert es nicht. Ich verwende .NET, MVC und habe einen Aufruf innerhalb der Controller-Methode. Ich erhalte immer noch eine Ausnahme, obwohl die Umleitung erfolgt.
FrenkyB
8

Eine Umleitung kann nur erfolgen, wenn die erste Zeile in einer HTTP-Nachricht " HTTP/1.x 3xx Redirect Reason" lautet .

Wenn Sie bereits Response.Write()einige Header aufgerufen oder festgelegt haben, ist es für eine Weiterleitung zu spät. Sie können versuchen, Response.Headers.Clear()vor der Umleitung anzurufen, um festzustellen, ob dies hilfreich ist.

Mark Cidade
quelle
Ich benutze return RedirectToAction("Logout", "Authentication");und ich bekomme diesen Fehler
Kiquenet
Beim Versuch, die Header zu löschen, wurde die System.PlatformNotSupportedException angezeigt: Für diesen Vorgang ist der integrierte IIS-Pipeline-Modus erforderlich.
IrishChieftain
3

Überprüfen Sie einfach, ob Sie die Pufferoption auf false gesetzt haben (standardmäßig true). Damit response.redirect funktioniert,

  1. Pufferung sollte wahr sein,
  2. Sie sollten nicht mehr Daten mit response.write gesendet haben, die die Standardpuffergröße überschreiten (in diesem Fall wird es sich selbst leeren, wodurch die Header gesendet werden), sodass Sie nicht umleiten können.

quelle
1
Response.BufferOutput = true;in der Aktion, in Controller?
Kiquenet
2

Verwenden return RedirectPermanent(myUrl)hat bei mir funktioniert

Vasilis
quelle
Ich habe Action und Controller
Kiquenet
2

Sie können auch den unten genannten Code verwenden

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

Hierfür gibt es eine einfache Antwort: Sie haben etwas anderes ausgegeben, z. B. Text oder etwas, das mit der Ausgabe Ihrer Seite zusammenhängt, bevor Sie Ihren Header senden. Dies wirkt sich darauf aus, warum Sie diesen Fehler erhalten.

Überprüfen Sie einfach Ihren Code auf mögliche Ausgaben, oder setzen Sie den Header über Ihre Methode, damit er zuerst gesendet wird.

DucDigital
quelle
1

Wenn Sie versuchen, nach dem Senden der Header umzuleiten (wenn Sie beispielsweise eine Fehlerumleitung von einer teilweise generierten Seite durchführen), können Sie Client-Javascript senden (location.replace oder location.href usw.). um zu einer beliebigen URL umzuleiten. Das hängt natürlich davon ab, welches HTML bereits gesendet wurde.

Brad
quelle
1

Mein Problem wurde behoben, indem der Exception Handler hinzugefügt wurde, um "Kann nicht umleiten, nachdem HTTP-Header gesendet wurden" zu behandeln. Dieser Fehler wie unten gezeigt

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
quelle
1

Ich habe das Problem gelöst mit: Response.RedirectToRoute ("CultureEnabled", RouteData.Values); anstelle von Response.Redirect.

utilsit
quelle
1

Fehler Kann nicht umgeleitet werden, nachdem HTTP-Header gesendet wurden.

System.Web.HttpException (0x80004005): Kann nicht umgeleitet werden, nachdem HTTP-Header gesendet wurden.

Vorschlag

Wenn wir asp.net mvc verwenden und auf demselben Controller arbeiten und zu einer anderen Aktion umleiten, müssen Sie nicht schreiben.
Response.Redirect ("ActionName", "ControllerName");
Es ist besser, nur
return RedirectToAction ("ActionName") zu verwenden.
oder
return View ("ViewName");

Ram Samuj
quelle
Ich verwende ActionName von einem anderen ControllerName.
Kiquenet
0

Die Umleitungsfunktion funktioniert wahrscheinlich mithilfe des http-Headers 'refresh' (und möglicherweise auch mithilfe eines 30X-Codes). Sobald die Header an den Client gesendet wurden, kann der Server diesen Umleitungsbefehl nicht mehr anhängen. Es ist zu spät.

Nathan
quelle
0

Wenn Sie nach dem Senden von HTTP-Headern keine Weiterleitung erhalten können, versuchen Sie diesen folgenden Code.

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

Stellen Sie sicher, dass Sie die ResponseMethoden von s nicht wie Response.Flush();vor dem Umleiten verwenden.

1_bug
quelle
-3

Es gibt zwei Möglichkeiten, dies zu beheben:

  1. Fügen Sie einfach eine returnAnweisung nach Ihrer hinzu Response.Redirect(someUrl); (wenn die Methodensignatur nicht "void" ist, müssen Sie diesen "Typ" natürlich zurückgeben), wie folgt:

    Response.Redirect ("Login.aspx");

    Rückkehr;

Beachten Sie, dass die Rückgabe es dem Server ermöglicht, die Umleitung durchzuführen. Ohne diese Umleitung möchte der Server den Rest Ihres Codes weiter ausführen.

  1. Machen Sie Response.Redirect(someUrl)die zuletzt ausgeführte Anweisung in der Methode, die die Ausnahme auslöst. Ersetzen Sie Ihre Response.Redirect(someUrl)durch eine Zeichenfolge VARIABLE mit dem Namen "someUrl" und setzen Sie sie auf die Umleitungsposition ... wie folgt:

//......some code

string someUrl = String.Empty

..... etwas Logik

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

...... mehr Code

// BEWEGE deine Antwort. Leite zu HIER um (das Ende der Methode):

Response.Redirect(someUrl);
return; 
user9150083
quelle
Entschuldigung, aber das macht für mich keinen Sinn. Was sollte diese redundante Methode (bei einer Methode zur Rückgabe von Leeren) returntun? Das returndefiniert nur, dass die Methode abgeschlossen ist. Wenn jedoch kein Code mehr vorhanden ist, ist die Methode trotzdem abgeschlossen. Und das Speichern einer URL in einer Variablen ändert nichts, ich meine: Warum sollte es? Die Zeichenfolge ist dieselbe. Das kompilierte Ding macht keinen Unterschied zwischen einem String und einer Variablen, die einen String enthält ...: Denken Sie darüber nach x = 5, also ist x 5, aber 5 ist auch 5. Selbst 10/2 wäre 5 ... macht auch keinen Unterschied
Matthias Burger