Wenn ein Webserver auf HttpWebRequest.GetResponse()
mit HTTP 304 reagiert (nicht geändert), GetResponse()
thows eine WebException
, die für mich so sehr seltsam ist. Ist das Absicht oder vermisse ich hier etwas Offensichtliches?HttpWebRequest.GetResponse wirft WebException auf HTTP 304
Antwort
Ok, das scheint ein By-Design-Verhalten und ein perfektes Beispiel für eine vexing exception. Dies kann mit dieser gelöst werden:
public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
try
{
return (HttpWebResponse) request.GetResponse();
}
catch (WebException ex)
{
if(ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError)
throw;
return (HttpWebResponse)ex.Response;
}
}
Das ist wirklich ein frustrierendes Problem, und kann alternativ um unter Verwendung der folgenden Erweiterungsmethode Klasse und ruft request.BetterGetResponse()
//-----------------------------------------------------------------------
//
// Copyright (c) 2011 Garrett Serack. All rights reserved.
//
//
// The software is licensed under the Apache 2.0 License (the "License")
// You may not use the software except in compliance with the License.
//
//-----------------------------------------------------------------------
namespace CoApp.Toolkit.Extensions {
using System;
using System.Net;
public static class WebRequestExtensions {
public static WebResponse BetterEndGetResponse(this WebRequest request, IAsyncResult asyncResult) {
try {
return request.EndGetResponse(asyncResult);
}
catch (WebException wex) {
if(wex.Response != null) {
return wex.Response;
}
throw;
}
}
public static WebResponse BetterGetResponse(this WebRequest request) {
try {
return request.GetResponse();
}
catch (WebException wex) {
if(wex.Response != null) {
return wex.Response;
}
throw;
}
}
}
}
Sie gearbeitet werden gelesen mehr darüber in meinem Blog-Post zu diesem Thema bei http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/
Die Art und Weise dieses System.WebException
ist zu vermeiden AllowAutoRedirect Eigenschaft auf false
einzustellen. Dies deaktiviert die automatische Umleitungslogik des WebRequest
. Es scheint für 304 Redirection-Anfragen defekt zu sein, da es sich nicht um eine echte Umleitung im engeren Sinne handelt. Das bedeutet natürlich, dass die anderen Umleitungsanforderungen 3xx
manuell bearbeitet werden müssen.
Absolut brillant. Warum sollte ich für die schwerfällige Ausnahmemaschinerie bezahlen, wenn ich sie nicht brauche? – jsuddsjr
Ich kam auch in dieser Frage mit dem Code:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
Log.Error("Unknown error occured", ex);
//throw;
}
Und es scheint, dass, wenn der Remoteserver-304-Status zurückkehrt muss es durch das Werfen dieser Fehler oder Rückkehr benutzerdefinierten 304 so der Browser zu Browser weitergegeben werden konnte zurückkehren Cache-Antwort. Andernfalls erhalten Sie wahrscheinlich eine leere Antwort vom Remote-Server.
Also in meinem Fall für ein normales Verhalten mit der richtigen Cache sollte Umgang es sein:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
throw;
Log.Error("Unknown error occured", ex);
}
Nur als FYI, dies ist ein Update für Anton Gogolev's answer, die die C# 6 (VS2015) when
Klausel verwendet. Es ist ein wenig weniger ärgerlich, wenn ein Debugger wie es ein Catchpoint entfernt:
public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
try
{
return (HttpWebResponse) request.GetResponse();
}
catch (WebException ex)
when (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
return (HttpWebResponse) ex.Response;
}
}
- 1. Http 404: Nicht gefunden (WebException)
- 2. HttpWebRequest.GetResponse() - Welche spezifischen Statuscodes verursachen eine Ausnahme?
- 3. Ferne Future verfallen Header und HTTP 304
- 4. Empfangen von HTTP 304-Code mit $ .ajax()
- 5. HTTPWebRequest.GetResponse() löst Verbindungsfehlerausnahme aus
- 6. NodeJS res.redirect, aber HTTP-Statuscode 304
- 7. Timeout Verhalten in HttpWebRequest.GetResponse() vs GetResponseAsync()
- 8. WebException beim Lesen des Antwortstreams einer WebException
- 9. Fehlerbehandlung von HttpWebRequest.GetResponse
- 10. HttpWebRequest.GetResponse() hängt beim zweiten Aufruf
- 11. Wie verhindert man HTTP 304 in Django Testserver
- 12. C# wie WebException mit Antwort Statuscode erstellen
- 13. Firefox Konsole wirft "kein Element gefunden" auf HTTP-204-Antwort
- 14. Abfangen einer bestimmten WebException (550)
- 15. akka http wirft EntityStreamException: Entity Stream abgeschnitten
- 16. Was ThreadAbortException verursachen kann, wenn ich HttpWebRequest.GetResponse() verwende
- 17. Ist HttpWebRequest.GetResponse erforderlich, um einen POST abzuschließen?
- 18. IE9 Fälschungen 304 nach Erhalt ETag
- 19. Windows-Dienst, der MessageSecurityException wirft
- 20. Toobar wirft Schatten auf TabLayout
- 21. Sonderzeichen auf HTTP-Anfrage
- 22. überprüfen HTTP-Response-
- 23. Big Hochladen von Dateien (WebException: Die Verbindung wurde unerwartet geschlossen)
- 24. mod_deflate auf Apache verursacht Browser 200 statt 304 zu tun?
- 25. Wie Apache HTTP-Antwort-Header-Größe zu reduzieren, während 304 nicht geändert
- 26. HttpWebRequest wirft Ausnahme für 404
- 27. Max-Alter und 304 nicht geändert Verarbeitung
- 28. 304: Nicht geändert und Front-End-Caching
- 29. Angular - Testen http Dienste mit httpBackend wirft unerwartete Ausnahme
- 30. HTTPWebRequest.GetResponse() fehlgeschlagen mit authentifizierten Anfragen über einen transparenten Proxy
Dies funktioniert meisten Fällen, aber einige Web-Server könnte eine Antwort Körper zurück, wenn ein 404-Fehler zurück. In diesem Fall würde der obige Code ein 404 behandeln, wie es ein 304 behandelt! – comshak
@comshak das ist ein "gut zu wissen." Der aufrufende Code muss sich dessen bewusst sein, was akzeptable Antwortcodes sind. – roufamatic
Ich habe auch '|| hinzugefügt ((HttpWebResponse) ex.Response) .StatusCode! = HttpStatusCode.NotModified' –