2010-08-31 29 views

Respuesta

181

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 
    } 
} 
+0

pero en caso de "connectfailure" excepción de webexception obtengo una respuesta como nula, en ese caso ¿cómo puedo obtener el código httpstatus – Rusty

+5

@rusty: no se puede. Si hay una falla de conexión, entonces no hay un código de estado HTTP que se obtenga. – LukeH

+4

Si el error es un ProtocolError, no tiene que comprobar la respuesta para null. Vea el comentario en el ejemplo en esta [página de MSDN] (http://msdn.microsoft.com/en-us/library/es54hw8e%28v=vs.110%29.aspx) –

1

No estoy seguro de si lo hay pero si existiera tal propiedad no se consideraría confiable. Un WebException se puede disparar por razones distintas a los códigos de error HTTP, incluidos los errores de red simples. Esos no tienen ese código de error http correspondiente.

¿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.

8

Esto sólo funciona 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; 
} 
+0

¿por qué solo se trata de 401 no autorizado en lugar de todos los posibles códigos de estado de error de HTTP? esta es la peor respuesta – ympostor

+1

@ympostor Esto es solo un ejemplo. Cualquier desarrollador razonable entiende esto. Tu comentario es el más irreflexivo que he leído aquí. – pr0gg3r

1

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

HttpStatusCode GetHttpStatusCode(WebException we) 
{ 
    if (we.Response is HttpWebResponse) 
    { 
     HttpWebResponse response = (HttpWebResponse)we.Response; 
     return response.StatusCode; 
    } 
    return 0; 
} 
13

Al utilizar el null-conditional operator (?.) se 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 status contendrá el HttpStatusCode. Cuando hay una falla más general como un error de red donde no se envía código de estado HTTP, entonces status será nulo. En ese caso, puede inspeccionar ex.Status para obtener el WebExceptionStatus.

Si lo que desea es una cadena descriptiva para iniciar la sesión en caso de un fallo puede utilizar el null-coalescing operator (??) para obtener el error relevante:

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

Si la excepción se produce como resultado de un 404 Código de estado HTTP 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 Microsoft IIS que sólo se registra en el servidor y nunca se envía al cliente.)

+0

No estoy seguro de si el operador '? .' se llamó originalmente operador de propagación nulo o operador con nulo-condicional durante la publicación de la 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 nulo-condicional. – RBT

+0

Un poco tarde para esta fiesta, pero justo advertencia de que el operador nulo-condicional es una característica de C# 6.0, por lo que uno necesita usar un compilador que lo admita. [Respuesta de desbordamiento de pila con más detalles] (https://stackoverflow.com/questions/39089426/how-to-install-the-ms-c-sharp-6-0-compiler). VS 2015+ lo tiene de manera predeterminada, pero si uno está utilizando cualquier tipo de entorno de compilación/implementación que no sea solo "su máquina", es posible que haya que tener en cuenta otras cosas. – CodeHxr

1

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

Una situación común en la que desea saber el código de respuesta es en el manejo de excepciones. A partir de C# 7, puede utilizar coincidencia de patrones que en realidad sólo entrar en la cláusula catch si la excepción coincida con su predicado:

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

Esto se puede extender fácilmente a otros niveles, como en este caso en el WebException era en realidad la excepción interna de otro (y sólo estamos interesados ​​en 404):

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

por último: Nótese cómo no hay necesidad de volver a emitir la excepción de la cláusula catch cuando no coincide con sus criterios, ya no ingresamos la cláusula en primer lugar con la solución anterior.

Cuestiones relacionadas