Codice di stato HTTP System.Net.WebException


Risposte:


248

Forse qualcosa del genere ...

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

ma in caso di eccezione "connectfailure" di webexception ricevo risposta come nulla, in quel caso come posso ottenere il codice httpstatus
Rusty

8
@rusty: non puoi. Se si verifica un errore di connessione, non è necessario ottenere un codice di stato HTTP.
Luca,

4
Se l'errore è un ProtocolError, non è necessario controllare la risposta per null. Vedi il commento nell'esempio in questa pagina MSDN
Andras Toth,

5
@AndrasToth Ma strumenti come ReSharper ti daranno un avvertimento se ometti il ​​controllo null. E in ogni caso, è buona norma programmare in modo difensivo.
Tom Lint,

1
Come ottenere il valore HTTP Substatus ? Ad esempio, 404.13 Riferimento troppo lungo alla lunghezza del contenuto : docs.microsoft.com/en-us/iis/configuration/system.webServer/…
Kiquenet

27

Utilizzando l' operatore null-conditional ( ?.) è possibile ottenere il codice di stato HTTP con una singola riga di codice:

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

La variabile statusconterrà il HttpStatusCode. Quando si verifica un errore più generale come un errore di rete in cui non viene mai inviato alcun codice di stato HTTP, questo statussarà nullo. In tal caso è possibile ispezionare ex.Statusper ottenere il WebExceptionStatus.

Se si desidera solo una stringa descrittiva per accedere in caso di errore, è possibile utilizzare l' operatore null-coalescing ( ??) per ottenere l'errore rilevante:

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

Se l'eccezione viene generata come risultato di un codice di stato HTTP 404, la stringa conterrà "NotFound". D'altra parte, se il server è offline la stringa conterrà "ConnectFailure" e così via.

(E per chiunque voglia sapere come ottenere il codice del substatus HTTP. Ciò non è possibile. È un concetto Microsoft IIS che è registrato solo sul server e non è mai inviato al client.)


Non sono sicuro se l' ?.operatore sia stato originariamente chiamato operatore di propagazione null o operatore null-condizionale durante la versione di anteprima. Ma il resharper di Atlassian avverte di utilizzare l'operatore di propagazione null in tali scenari. Bello sapere che è anche chiamato operatore nullo-condizionale.
RBT

1
Un po 'in ritardo per questa parte, ma un equo avviso che l'operatore null-condizionale è una funzionalità di C # 6.0, quindi è necessario utilizzare un compilatore che lo supporti. Stack Overflow rispondi con ulteriori dettagli . VS 2015+ ce l'ha per impostazione predefinita, ma se si utilizza qualsiasi tipo di ambiente di build / deploy diverso dalla "loro macchina", potrebbe essere necessario prendere in considerazione altre cose.
CodeHxr

9

funziona solo se WebResponse è 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;
}

perché gestire solo 401-Non autorizzato invece di tutti i possibili codici di stato dell'errore HTTP? questa è la risposta peggiore
ympostor

4
@ympostor Questo è solo un esempio. Qualsiasi sviluppatore ragionevole lo capisce. Il tuo commento è il più spensierato che abbia mai letto qui.
pr0gg3r,

9

(Mi rendo conto che la domanda è vecchia, ma è tra i migliori successi su Google.)

Una situazione comune in cui si desidera conoscere il codice di risposta è la gestione delle eccezioni. A partire da C # 7, puoi utilizzare la corrispondenza del modello per inserire effettivamente la clausola catch solo se l'eccezione corrisponde al tuo predicato:

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

Questo può essere facilmente esteso ad ulteriori livelli, come in questo caso in cui la WebExceptionvera era l'eccezione interiore di un altro (e ci interessa solo 404):

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

Infine: nota come non sia necessario ripetere l'eccezione nella clausola catch quando non soddisfa i tuoi criteri, dal momento che non inseriamo la clausola in primo luogo con la soluzione sopra.


4

Puoi provare questo codice per ottenere il codice di stato HTTP da WebException. Funziona anche in Silverlight perché SL non ha WebExceptionStatus.ProtocolError definito.

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

1
return 0? o meglio HttpStatusCode?( nullable )?
Kiquenet,

Funzionerà? var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF,

Non riesco a capire cosa volessi fare in questo esempio. In quali casi si desidera che l'evento venga registrato?
Sergey,

1

Non sono sicuro che ci sia, ma se ci fosse una tale proprietà non sarebbe considerata affidabile. A WebExceptionpuò essere attivato per motivi diversi dai codici di errore HTTP, inclusi semplici errori di rete. Quelli non hanno tale codice di errore http corrispondente.

Puoi darci qualche informazione in più su ciò che stai cercando di realizzare con quel codice. Potrebbe esserci un modo migliore per ottenere le informazioni di cui hai bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.