Gdy serwer WWW odpowiada HttpWebRequest.GetResponse()
z HTTP 304 (Not Modified), GetResponse()
thows się WebException
, która jest tak bardzo dziwne dla mnie. Czy jest to zgodne z projektem, czy też brakuje tu czegoś oczywistego?HttpWebRequest.GetResponse rzuca WebException na HTTP 304
Odpowiedz
OK, wydaje się, że jest to zachowanie towarzyszące projektowi i doskonałym przykładem modelu vexing exception. Problem ten można rozwiązać z tym:
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;
}
}
To jest naprawdę frustrujące problemu, a alternatywnie można obejść stosując następujące metody rozszerzenie klasy i nazywając 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;
}
}
}
}
czytasz więcej na ten temat na moim blogu na ten temat w http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/
sposobem na uniknięcie tego System.WebException
jest ustawienie AllowAutoRedirect właściwość false
. Powoduje wyłączenie automatycznej logiki przekierowania urządzenia WebRequest
. Wygląda na to, że jest uszkodzony dla 304 żądań przekierowania, ponieważ nie jest prawdziwym przekierowaniem w ścisłym tego słowa znaczeniu. Oczywiście oznacza to, że inne żądania przekierowania muszą być obsługiwane ręcznie.
Absolutnie genialny. Po co mam płacić za maszyny do obsługi wyjątków, jeśli ich nie potrzebuję? – jsuddsjr
doszedłem również w całej tej kwestii z kodem:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
Log.Error("Unknown error occured", ex);
//throw;
}
I wydaje się, że jeśli zdalny serwer zwraca 304 stan musi być przekazany do przeglądarki rzucając ten błąd lub powrocie zwyczaj 304 więc przeglądarka może wrócić buforowana odpowiedź. W przeciwnym razie prawdopodobnie otrzymasz pustą odpowiedź z serwera zdalnego.
Więc w moim przypadku do normalnego zachowania z prawidłową obsługę Cache powinno być tak:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
throw;
Log.Error("Unknown error occured", ex);
}
tylko jako FYI, jest to aktualizacja do Anton Gogolev's answer że używa C# 6 (VS2015) when
klauzuli. To trochę mniej irytujące, gdy za pomocą debuggera, gdyż usuwa jedną catchpoint:
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. konsola Firefox rzuca na odpowiedź HTTP 204
- 2. Jak zapobiec HTTP 304 w serwerze testowym Django
- 3. Obsługa błędów z HttpWebRequest.GetResponse
- 4. HttpWebRequest.GetResponse() staje się coraz timed out
- 5. 304 niezmodyfikowane w plikach statycznych
- 6. Uzyskaj numer błędu w błędzie WebException
- 7. Nie można znaleźć HttpWebRequest.GetResponse() w projekcie WP7
- 8. StructureMap rzuca ArgumentNullException na HttpContext
- 9. MVEL2 na Androida rzuca wyjątek
- 10. Jak poznać długość odpowiedzi (HttpWebRequest.GetResponse(). GetResponseStream())
- 11. 304: Nie zmodyfikowane i buforowanie z przodu
- 12. Jak zmniejszyć apache rozmiar nagłówka odpowiedzi HTTP podczas 304 Not Modified
- 13. spark.ml StringIndexer rzuca "Niewidoczna etykieta" na dopasowanie()
- 14. zwroty ekspresowe 304 dla żądań powtórzeń IE
- 15. 304 Not Modified z 200 (z bufora)
- 16. rzuca UnsupportedOperationException
- 17. Selenium WebDriver sporadycznie rzuca wyjątki Timeout
- 18. Formularze Xamarin https z certyfikatami klienta zgłasza wyjątek WebException
- 19. WebException, jak uzyskać pełną odpowiedź za pomocą ciała?
- 20. Nginx - "force" 200 odpowiedź cache zamiast 304
- 21. Błąd "Serwer zdalny zwrócił błąd: (403) Zabroniono", gdy skrobanie ekranu za pomocą HttpWebRequest.GetResponse()
- 22. Mockito rzuca OutOfMemoryError na prostym teście
- 23. Perl rzuca "klawisze na odniesienie jest eksperymentalna"
- 24. zapobiec niepożądanym nagłówki po powrocie 304 Not Modified z ServiceStack
- 25. Rzuca kosztowną operację?
- 26. Jak powrócić ze stanu 304 FileResult w ASP.NET MVC RC1
- 27. reinterpret_cast rzuca dala kwalifikatorów
- 28. Type.GetType() rzuca StackOverflowException
- 29. GetAuthorizationGroups() rzuca wyjątek
- 30. Dlaczego EndGetResponse rzuca ArgumentNullException?
Działa większości przypadków, ale niektóre serwery WWW może powrócić do ciała reakcji po powrocie błąd 404. W takim przypadku powyższy kod potraktuje 404, ponieważ traktuje 304! – comshak
@comshak to "dobrze wiedzieć". Kod wywołujący musi być świadomy, jakie są dopuszczalne kody odpowiedzi. – roufamatic
Dodałem także '|| ((HttpWebResponse) ex.Response) .StatusCode! = HttpStatusCode.NotModified' –