Código de estado HTTP System.Net.WebException

Respuestas:

248

Tal vez algo como esto ...

try
{
    // ...
}
catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        }
        else
        {
            // no http status code available
        }
    }
    else
    {
        // no http status code available
    }
}
LukeH
fuente
pero en caso de excepción "connectfailure" de webexception obtengo una respuesta nula, en ese caso, ¿cómo puedo obtener el código httpstatus
Rusty
8
@ oxidado: No puedes. Si hay una falla de conexión, entonces no hay ningún código de estado HTTP que se pueda obtener.
LukeH
44
Si el error es un ProtocolError, no tiene que verificar la respuesta para nulo. Vea el comentario en el ejemplo en esta página de MSDN
Andras Toth
55
@AndrasToth Pero herramientas como ReSharper le darán una advertencia si omite la verificación nula. Y en cualquier caso, es una buena práctica codificar a la defensiva.
Tom Lint
1
¿Cómo obtener el valor de HTTP Substatus ? Por ejemplo, 404.13 Contenido Longitud demasiado grande Referencia : docs.microsoft.com/en-us/iis/configuration/system.webServer/…
Kiquenet
27

Al usar el operador condicional nulo ( ?.) puede obtener el código de estado HTTP con una sola línea de código:

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

La variable statuscontendrá el HttpStatusCode. Cuando hay una falla más general como un error de red donde nunca se envía un código de estado HTTP, entonces statusserá nulo. En ese caso, puede inspeccionar ex.Statuspara obtener el WebExceptionStatus.

Si solo desea que se registre una cadena descriptiva en caso de falla, puede usar el operador de fusión nula ( ??) para obtener el error relevante:

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

Si se produce la excepción como resultado de un código de estado HTTP 404, la cadena contendrá "NotFound". Por otro lado, si el servidor está fuera de línea, la cadena contendrá "ConnectFailure" y así sucesivamente.

(Y para cualquiera que quiera saber cómo obtener el código de subestado HTTP. Eso no es posible. Es un concepto de Microsoft IIS que solo se registra en el servidor y nunca se envía al cliente).

Martin Liversage
fuente
No estoy seguro de si el ?.operador se denominó originalmente operador de propagación nulo o operador condicional nulo durante la versión de vista previa. Pero Atlassian Resharper da una advertencia para usar un operador de propagación nulo en tales escenarios. Es bueno saber que también se llama operador condicional nulo.
RBT
1
Un poco tarde para esta fiesta, pero una advertencia justa de que el operador condicional nulo es una característica de C # 6.0, por lo que uno debe estar usando un compilador que lo admita. Respuesta de desbordamiento de pila con más detalles . VS 2015+ lo tiene por defecto, pero si uno está usando cualquier tipo de entorno de construcción / implementación que no sea solo "su máquina", es posible que se deban tomar en cuenta otras cosas.
CodeHxr
9

esto funciona solo si WebResponse es un HttpWebResponse.

try
{
    ...
}
catch (System.Net.WebException exc)
{
    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        MessageBox.Show("401");
    }
    else
        throw;
}
pr0gg3r
fuente
¿Por qué solo tratar con 401 no autorizados en lugar de todos los posibles códigos de estado de error HTTP? esta es la peor respuesta
ympostor
44
@ympostor Esto es solo un ejemplo. Cualquier desarrollador razonable entiende esto. Tu comentario es el más irreflexivo que he leído aquí.
pr0gg3r
9

(Me doy cuenta de que la pregunta es antigua, pero está entre los principales éxitos de Google).

Una situación común en la que desea conocer el código de respuesta es el manejo de excepciones. A partir de C # 7, puede usar la coincidencia de patrones para ingresar solo la cláusula catch si la excepción coincide con su predicado:

catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
     doSomething(response.StatusCode)
}

Esto puede extenderse fácilmente a otros niveles, como en este caso donde en WebExceptionrealidad era la excepción interna de otro (y solo nos interesa 404):

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

Finalmente: tenga en cuenta que no es necesario volver a lanzar la excepción en la cláusula catch cuando no coincide con sus criterios, ya que no ingresamos la cláusula en primer lugar con la solución anterior.

miniyou
fuente
4

Puede probar este código para obtener el código de estado HTTP de WebException. También funciona en Silverlight porque SL no tiene WebExceptionStatus.ProtocolError definido.

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}
Sergey
fuente
1
return 0? o mejor HttpStatusCode?( anulable )?
Kiquenet
esto funcionara? var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF
No puedo entender lo que querías hacer en esta muestra. ¿En qué casos desea que se registre el evento?
Sergey
1

No estoy seguro de si existe, pero si existiera dicha propiedad, no se consideraría confiable. A WebExceptionpuede ser despedido por otros motivos que no sean códigos de error HTTP, incluidos simples errores de red. Los que no tienen ese código de error http coincidente.

¿Puede darnos un poco más de información sobre lo que está tratando de lograr con ese código? Puede haber una mejor manera de obtener la información que necesita.

JaredPar
fuente