.net - ejemplo - webrequest create
HttpWebRequest.GetResponse lanza WebException en HTTP 304 (5)
Cuando un servidor web responde a HttpWebRequest.GetResponse()
con HTTP 304 (no modificado), GetResponse()
emite una WebException
, lo cual es muy extraño para mí. ¿Es esto por diseño o me falta algo obvio aquí?
Al igual que para su información, esta es una actualización de la respuesta de Anton Gogolev que utiliza la cláusula C # 6 (VS2015). Es un poco menos molesto cuando se utiliza un depurador, ya que elimina un punto de captura:
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;
}
}
Este es realmente un problema frustrante, y se puede solucionar alternativamente utilizando la siguiente clase de método de extensión y llamando a 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;
}
}
}
}
Leíste más sobre eso en mi blog sobre este tema en http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/
La forma de evitar esta System.WebException
es establecer la propiedad AllowAutoRedirect en false
. Esto deshabilita la lógica de redirección automática de la WebRequest
de WebRequest
. Parece estar roto para 304 solicitudes de redirección, ya que no es una redirección real en el sentido más estricto. Por supuesto, eso significa que las otras solicitudes de redireccionamiento 3xx
deben manejarse manualmente.
Ok, esto parece ser un comportamiento de diseño y un ejemplo perfecto de una excepción desconcertante . Esto se puede resolver con esto:
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;
}
}
También me topé con este problema con el código:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
Log.Error("Unknown error occured", ex);
//throw;
}
Y parece que si el servidor remoto devuelve el estado 304, debe pasarse al navegador lanzando este error o devolviendo el 304 personalizado para que el navegador pueda devolver la respuesta en caché. De lo contrario, probablemente obtendrá una respuesta vacía del servidor remoto.
Entonces, en mi caso, el comportamiento normal con el manejo correcto de la memoria caché debería ser como:
try
{
...
var webResponse = req.GetResponse();
...
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
throw;
Log.Error("Unknown error occured", ex);
}