ti-enxame.com

Código de status HTTP System.Net.WebException

Existe uma maneira fácil de obter o código de status HTTP de um System.Net.WebException?

139
Gilsham

Talvez algo assim ...

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
    }
}
226
LukeH

Usando o operador condicional nulo (?.) você pode obter o código de status HTTP com uma única linha de código:

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

A variável status conterá o HttpStatusCode . Quando há uma falha mais geral, como um erro de rede, em que nenhum código de status HTTP é enviado, status será nulo. Nesse caso, você pode inspecionar ex.Status para obter o WebExceptionStatus .

Se você quer apenas uma string descritiva para registrar no caso de uma falha, você pode usar o operador de coalescência nula (??) para obter o erro relevante:

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

Se a exceção for lançada como resultado de um código de status HTTP 404, a cadeia conterá "NotFound". Por outro lado, se o servidor estiver offline, a cadeia conterá "ConnectFailure" e assim por diante.

(E para qualquer um que queira saber como obter o código do substatus HTTP. Isso não é possível. É um conceito Microsoft IIS que é registrado apenas no servidor e nunca é enviado para o cliente.)

23
Martin Liversage

isso funciona apenas se o WebResponse for um 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;
}
8
pr0gg3r

(Eu sei que a pergunta é antiga, mas está entre os principais hits do Google.)

Uma situação comum em que você deseja saber o código de resposta está no tratamento de exceções. A partir do C # 7, você pode usar a correspondência de padrões para inserir apenas a cláusula catch se a exceção corresponder ao seu predicado:

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

Isso pode ser facilmente estendido para níveis adicionais, como neste caso onde o WebException era na verdade a exceção interna de outro (e estamos interessados ​​apenas em 404):

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

Finalmente: observe como não há necessidade de lançar novamente a exceção na cláusula catch quando ela não corresponde aos seus critérios, uma vez que não entramos na cláusula em primeiro lugar com a solução acima.

6
miniyou

Você pode tentar este código para obter o código de status HTTP do WebException. Ele também funciona no Silverlight porque o SL não possui WebExceptionStatus.ProtocolError definido.

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}
3
Sergey

Eu não tenho certeza se existe, mas se houvesse tal propriedade, não seria considerado confiável. Um WebException pode ser acionado por razões diferentes de códigos de erro HTTP, incluindo erros simples de rede. Aqueles que não têm esse código de erro http correspondente.

Você pode nos dar um pouco mais de informações sobre o que você está tentando realizar com esse código? Pode haver uma maneira melhor de obter as informações de que você precisa.

1
JaredPar