मैं 404 कैसे पकड़ सकता हूं?


93

मेरे पास निम्नलिखित कोड हैं:

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

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

मैं एक विशिष्ट 404 त्रुटि कैसे पकड़ सकता हूं? WebExceptionStatus.ProtocolError केवल यह पता लगा सकती है कि कोई त्रुटि हुई, लेकिन त्रुटि का सटीक कोड न दें।

उदाहरण के लिए:

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

क्या सिर्फ पर्याप्त उपयोगी नहीं है ... प्रोटोकॉल अपवाद 401, 503, 403, कुछ भी हो सकता है।


13
NNNOOOOOOOOOOOOO! पकड़ मत करो System.Exception, और अपने हैंडलर में अपवाद पाठ पर निर्भर न करें!
आरोनोन

2
जॉन सॉन्डर्स का जवाब सबसे पूर्ण था। मुझे लगता है कि लोगों ने उसे उलाहना देने के बावजूद नीचे गिरा दिया।
आरोनॉट

3
उपयोग न करें throw ex, आप एक खाली कॉल स्टैक के साथ एक नया अपवाद उत्पन्न करेंगे। बस उपयोग करें throw
krbnr

1
मैंने हमेशा खुद को निराश करते हुए पाया है। यदि आपको एक अच्छी तरह से गठित प्रतिक्रिया मिलती है, तो एक अपवाद नहीं फेंका जाना चाहिए, और एक प्रोटोकॉल त्रुटि संदेश निश्चित रूप से अच्छी तरह से बनता है। कक्षा को उपयोगकर्ता को परिणामों की व्याख्या करने और तदनुसार कार्य करने की अनुमति देनी चाहिए।
जेरेमी होलोवेक 13

@JeremyHolovacs अपवाद अब नए http क्लाइंट में 404 जैसी चीजों के लिए नहीं फेंके गए हैं। "नियंत्रण प्रवाह के लिए अपवादों का उपयोग न करें" जो टीम का निर्माण करने के लिए जीवित नहीं थाWebRequest
मैट कोकाज

जवाबों:


113

HttpStatusCode Enumerationविशेष रूप से उपयोग करेंHttpStatusCode.NotFound

कुछ इस तरह:

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

कहां
weहै a WebException


क्या मैं अपनी लुकअप सूची बनाये बिना ही वस्तुओं से किसी तरह NUMBER निकाल सकता हूँ? मैं कुछ ऐसा करना चाहूंगा: int canpresponsons दिल्लगी = HttpStatusCode.ToInt () या इसी तरह से मुझे 404 मिलता है
BerggreenDK

2
@BerggreenDK आपको सिर्फ intprespresonsecode = (int) HttpStatusCode.NotFound
Trev

7
-1 मेरे प्राचीन डाउनवोट का आंशिक विवरण: कोड किसी कारण से, NullReferenceException को फेंकता है, we.Responseनहीं है HttpWebResponse। यदि कोड यह मानना ​​चाहता है कि यह हमेशा उस प्रकार का होगा, तो उसे बस कास्ट करना चाहिए HttpWebResponse errorResponse = (HttpWebResponse)we.Response;:। यह एक स्पष्ट फेंक देगा InvalidCastExceptionयदि एक रहस्यमय के बजाय असंभव होता है NullReferenceException
जॉन सॉन्डर्स

मुझे An object reference is required for the non-static field, method, or property 'WebException.Response'इस कोड का उपयोग करना है।
जेमी

122
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 @ एक आईडी का उपयोग करने वाली पुलिस होने के नाते और सभी को -1 का उपयोग ब्लॉक में प्रतिक्रिया को न लपेटने के लिए दे रही है।
रिच

2
यह एक कठिन काम है, लेकिन किसी को यह करना है। OTOH, मैंने लगभग इस उत्तर को नहीं जोड़ा, क्योंकि ऐसा लग सकता है कि मैं अन्य सभी को टॉप-रेटेड उत्तर देने के लिए चक्कर काट रहा था।
जॉन सॉन्डर्स

3
मैंने वास्तव में उत्थान किया, लेकिन मैंने सिर्फ एक बात पर ध्यान दिया: throwआपके अंत में शायद (रीथ्रो) होना चाहिए catch, अन्यथा यह चुपचाप किसी अन्य प्रकार का भोजन करेगा WebException
आरोनॉट

@ जॉन सॉन्डर्स: आपके पास आपके अनुरोध के आसपास भी ऐसा क्यों नहीं है?
जोएल एथरटन

1
@Joel: WebRequestलागू नहीं होता है IDisposable
जॉन सॉन्डर्स

23

C # 6 में आप अपवाद फ़िल्टर का उपयोग कर सकते हैं ।

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
}

एक बहुत अच्छी सुविधा जो मैं देख रहा हूँ! मैं केवल 401 को पकड़ने के लिए तरीकों की मांग करता रहा, जबकि दूसरों को सामान्य अपवाद हैंडलर से गुजरने दिया। जाने का यह रास्ता है!
लियोनेट चेन

12

मैंने इसका परीक्षण नहीं किया है, लेकिन यह काम करना चाहिए

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

@ जॉन सॉन्डर्स - मैं ओपी के कोड को अनुकूलित कर रहा था, इसे अनुकूलित नहीं कर रहा था।
MiffTheFox

@ जॉन - और शायद मैं केवल catchब्लॉक की कॉपी / पेस्ट करने की उम्मीद कर रहा था , यह देखकर कि ओपी के रूप में मेरे पास कोशिश में बिल्कुल समान कोड था। आपको वास्तव में ओपी के कोड के कारण इस प्रश्न को पूरी तरह से नीचा दिखाना चाहिए।
MiffTheFox

1
@ जॉन हम यहाँ भूल गए नमूना कोड है। यह मामला है यह 404 का एक और तरीका है, न कि GetResponse का उपयोग कैसे करें। -1 थोड़ा कठोर लगता है। प्रश्न का उत्तर देने के लिए +1 से मिफ़ करें।
डेविड बसाराब

@ मुझे लगता है कि यह अच्छा है कि आप इसे एक टिप्पणी में इंगित करें। जिस तरह से मैं नीचे वोटिंग को देखता हूं, अगर दिया गया कोड समस्या को हल नहीं करता है। डाउन वोट निकालने के लिए धन्यवाद।
डेविड बसाराब

@ जॉन - ठीक है, मैं सब कुछ से छुटकारा पा लिया लेकिन पकड़, अब खुश?
MiffTheFox

4

मुझे लगता है कि यदि आप एक WebException को पकड़ते हैं, तो वहाँ कुछ जानकारी है जिसे आप यह निर्धारित करने के लिए उपयोग कर सकते हैं कि यह 404 था। यही एकमात्र तरीका है जो मुझे इस समय पता है ... मुझे किसी अन्य को जानने में दिलचस्पी होगी ...

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

2

इस स्निपिट को देखें। GetResponse एक WebRequestException को फेंक देगा। उसे पकड़ो और आप प्रतिक्रिया से स्थिति कोड प्राप्त कर सकते हैं।

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

यह http://msdn.microsoft.com/en-us/library/system.net.webexception.stat.nic.in से आया है


2

उचित अपवाद प्रकार को पकड़ो 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");
}

@ जॉन सॉन्डर्स मैं आपसे वहां बहस नहीं करता, लेकिन यह सवाल नहीं था, उन्होंने 404 पर कब्जा करने का सबसे अच्छा तरीका पूछा। उनके कोड में मेरे बदलाव सवाल का जवाब देने तक सीमित थे, बदलाव को सरल और स्पष्ट बनाने के लिए मुमकिन।
निक Craver

@ जॉन सॉन्डर्स: फिक्स्ड, मुझे लगता है "अगर यह सबसे कुशल है" तो यह सवाल पर लागू होता है।
निक Craver

बस पहुँच प्राप्त करने से पहले के e.Responseरूप में डाली थी । HttpWebResponseStatusCode
लंकिमार्ट

2

प्रतिक्रिया की स्थिति के बारे में MSDN पर देखें :

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

2
@ जॉन सॉन्डर्स - मैं इसे MSDN के साथ पास करने से अधिक खुश रहूंगा (जहां मैंने नमूना ... से कॉपी किया था)। इस कोड का उद्देश्य StatusCode का उपयोग दिखाना है, जितना संभव हो उतना कुशल नहीं है।
Dror

2
@ जॉन सॉन्डर्स - मैंने केवल वही हिस्सा छोड़ा जो मैं दिखाना चाहता था, बस आपके लिए :-)
Dror

2

यह ब्राउज़ करने वाले VB.NET लोगों के लिए, मेरा मानना ​​है कि हम अपवाद को तभी पकड़ सकते हैं जब यह वास्तव में 404 हो। कुछ इस तरह:

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

1

जब WebRequest वर्ग का उपयोग कर सर्वर पर POST या GET डेटा आता है तो अपवाद का प्रकार WebException.Below होगा फ़ाइल के लिए कोड अपवाद नहीं मिला है

        //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);
                    }

                }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.