75

Ho il seguente codice:Come posso prendere un 404?

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
request.Method = "HEAD"; 
request.Credentials = MyCredentialCache; 

try 
{ 
    request.GetResponse(); 
} 
catch 
{ 
} 

Come posso prendere una specifica errore 404? Il WebExceptionStatus.ProtocolError può solo rilevare che si è verificato un errore, ma non fornire il codice esatto dell'errore.

Ad esempio:

catch (WebException ex) 
{ 
    if (ex.Status != WebExceptionStatus.ProtocolError) 
    { 
     throw ex; 
    } 
} 

non è utile soltanto abbastanza ... l'eccezione protocollo potrebbe essere 401, 503, 403, nulla di veramente.

+11

** NNNOOOOOOOOOOOOO! ** Non prendere 'System.Exception', e non dipendere dal testo di eccezione nel gestore! – Aaronaught

+2

Quindi cosa consiglieresti? – Luke101

+2

La risposta di John Saunders è stata la più completa. Penso che la gente lo abbia semplicemente offuscato per dispetto. – Aaronaught

risposta

92

Usare il HttpStatusCode Enumeration, specificamente HttpStatusCode.NotFound

Qualcosa di simile:

HttpWebResponse errorResponse = we.Response as HttpWebResponse; 
if (errorResponse.StatusCode == HttpStatusCode.NotFound) { 
    // 
} 

W qui
we è un WebException.

+0

Sì, è l'ideale ... ha funzionato come un incantesimo, grazie ancora! –

+0

posso ottenere il NUMERO in qualche modo dagli oggetti senza creare il mio elenco di ricerca? Mi piacerebbe avere qualcosa di simile: int httpresponsecode = HttpStatusCode.ToInt() o simile quindi ottengo 404 – BerggreenDK

+2

@BerggreenDK dovresti essere in grado di fare solo int httpresonsecode = ** (int) ** HttpStatusCode.NotFound – Trev

4

Penso che se si cattura un WebException ci sono alcune informazioni in là che è possibile utilizzare per determinare se fosse un 404. Questo è l'unico modo che conosco al momento ... Sarei interessato a conoscere qualsiasi altri ...

catch(WebException e) { 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
     var statusCode = (HttpWebResponse)e.Response).StatusCode); 
     var description = (HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
2

Dai un'occhiata a questo snipit. GetResponse genererà un'eccezione WebRequestException. Catturalo e puoi ottenere il codice di stato dalla risposta.

try { 
    // Create a web request for an invalid site. Substitute the "invalid site" strong in the Create call with a invalid name. 
    HttpWebRequest myHttpWebRequest = (HttpWebRequest) WebRequest.Create("invalid site"); 

    // Get the associated response for the above request. 
    HttpWebResponse myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse(); 
    myHttpWebResponse.Close(); 
} 
catch(WebException e) { 
    Console.WriteLine("This program is expected to throw WebException on successful run."+ 
         "\n\nException Message :" + e.Message); 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
     Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode); 
     Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
catch(Exception e) { 
    Console.WriteLine(e.Message); 
} 

questo è venuto da http://msdn.microsoft.com/en-us/library/system.net.webexception.status.aspx

2

vediamo al MSDN sullo stato della risposta:

... 
catch(WebException e) { 
    Console.WriteLine("The following error occured : {0}",e.Status); 
} 
... 
+2

@John Saunders - Sarò più che felice di trasmetterlo a MSDN (dove ho copiato il campione da ...). Lo scopo di questo codice è mostrare l'uso di StatusCode, non essere il più efficiente possibile. – Dror

+1

@John Saunders - Ho lasciato solo la parte che volevo mostrare, Solo per te :-) – Dror

13

non ho ancora testato questo, ma dovrebbe funzionare

try 
{ 
    // TODO: Make request. 
} 
catch (WebException ex) 
{ 
    if (ex.Status == WebExceptionStatus.ProtocolError) { 
     HttpWebResponse resp = ex.Response as HttpWebResponse; 
     if (resp != null && resp.StatusCode == HttpStatusCode.NotFound) 
     { 
      // TODO: Handle 404 error. 
     } 
     else 
      throw; 
    } 
    else 
     throw; 
} 
+0

@John Saunders - Stavo adattando il codice dell'OP, non ottimizzandolo. – MiffTheFox

+0

@John - E forse mi aspettavo solo che copiassero/incollassero il blocco 'catch', visto che avevo lo stesso esatto codice nel tentativo dell'OP. Dovresti davvero mandare giù questa domanda del tutto a causa del codice OP allora. – MiffTheFox

+1

@John ci dimentichiamo che qui è un codice di esempio. Questo è il caso in cui è un altro modo per 404, non come usare GetResponse. -1 sembra un po 'duro. +1 a Miff per rispondere alla domanda. –

1

Cattura il corretto tipo di eccezione WebException:

try 
{ 
    var request = (HttpWebRequest) WebRequest.Create(String.Format("http://www.gravatar.com/avatar/{0}?d=404", hashe)); 

    using(var response = (HttpWebResponse)request.GetResponse()) 
     Response.Write("has avatar"); 
} 
catch(WebException e) 
{ 
    if(e.Response.StatusCode == 404) 
    Response.Write("No avatar"); 
} 
+0

@John Saunders Non ti discuto lì, ma non era questa la domanda, ha chiesto il modo migliore per catturare un 404. Le mie modifiche al suo codice erano limitate a rispondere alla domanda, per rendere il cambiamento semplice e ovvio il più possibile –

+0

@John Saunders: corretto, suppongo che "se questo è il più efficiente" si applica alla domanda. –

111
try 
{ 
    var request = WebRequest.Create(uri); 
    using (var response = request.GetResponse()) 
    { 
     using (var responseStream = response.GetResponseStream()) 
     { 
      // Process the stream 
     } 
    } 
} 
catch (WebException ex) 
{ 
    if (ex.Status == WebExceptionStatus.ProtocolError && 
     ex.Response != null) 
    { 
     var resp = (HttpWebResponse) ex.Response; 
     if (resp.StatusCode == HttpStatusCode.NotFound) 
     { 
      // Do something 
     } 
     else 
     { 
      // Do something else 
     } 
    } 
    else 
    { 
     // Do something else 
    } 
} 
+10

lol @ è la polizia IDisposable e dà a tutti un -1 per non aver completato la risposta in un blocco usando. – Rich

+2

È un lavoro difficile, ma _someone_ deve farlo. OTOH, non ho quasi aggiunto questa risposta, dal momento che potrebbe sembrare che stavo facendo del male a tutti gli altri per rendere la mia la migliore risposta. –

+3

In realtà ho svalutato, ma ho appena notato una cosa: ci dovrebbe essere probabilmente un 'throw' (rethrow) alla fine del tuo' catch', altrimenti questo semplicemente mangierà in silenzio qualsiasi altro tipo di 'WebException'. – Aaronaught

2

Per le persone che stanno navigando nel VB.NET, credo che siamo in grado di intercettare l'eccezione solo se è veramente un 404. Qualcosa di simile:

Try 
    httpWebrequest.GetResponse() 
Catch we As WebException When we.Response IsNot Nothing _ 
           AndAlso TypeOf we.Response Is HttpWebResponse _ 
           AndAlso (DirectCast(we.Response, HttpWebResponse).StatusCode = HttpStatusCode.NotFound) 

    ' ... 

End Try 
+0

Tu credi che puoi? Si prega di provare e poi dire "sì" o "no". –

10

In C# 6 è possibile utilizzare exception filters.

try 
{ 
    var request = WebRequest.Create(uri); 
    using (var response = request.GetResponse()) 
    using (var responseStream = response.GetResponseStream()) 
    { 
     // Process the stream 
    } 
} 
catch(WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) 
{ 
    // handle 404 exceptions 
} 
catch (WebException ex) 
{ 
    // handle other web exceptions 
} 
+0

Una caratteristica molto interessante che ho trascurato! Ho continuato a cercare metodi per catturare solo 401 mentre lasciavo che altri passassero al gestore di eccezioni generale. Questa è la strada da percorrere! –

0

quando il POST o GET dati al server utilizzando classe WebRequest poi il tipo di eccezione sarebbe WebException.Below è il codice per il file non trovato eccezione

 //Create a web request with the specified URL 
      string path = @"http://localhost/test.xml1"; 
      WebRequest myWebRequest = WebRequest.Create(path); 

     //Senda a web request and wait for response. 
       try 
       { 
        WebResponse objwebResponse = myWebRequest.GetResponse(); 
        Stream stream= objwebResponse.GetResponseStream(); 

       } 
       catch (WebException ex) { 
        if (((HttpWebResponse)(ex.Response)).StatusCode == HttpStatusCode.NotFound) { 
         throw new FileNotFoundException(ex.Message); 
        } 

       } 
Problemi correlati