Webclient से स्टेटस कोड कैसे प्राप्त करें?


90

मैं WebClientवेब फॉर्म में कुछ डेटा पोस्ट करने के लिए क्लास का उपयोग कर रहा हूं । मैं फॉर्म सबमिट करने की प्रतिक्रिया स्थिति कोड प्राप्त करना चाहूंगा। अब तक मुझे पता चला है कि यदि अपवाद है तो स्थिति कोड कैसे प्राप्त करें

Catch wex As WebException
        If TypeOf wex.Response Is HttpWebResponse Then
          msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
            End If

हालाँकि, यदि फॉर्म सफलतापूर्वक सबमिट किया गया है और कोई अपवाद नहीं डाला गया है, तो मुझे स्टेटस कोड (200,301,302, ...) पता नहीं चलेगा

जब कोई अपवाद नहीं है तो क्या स्थिति कोड प्राप्त करने का कोई तरीका है?

पुनश्च: मैं httpwebrequest / httpwebresponse का उपयोग नहीं करना पसंद करता हूँ

जवाबों:


23

इसे बाहर करने की कोशिश की। ResponseHeaders में स्थिति कोड शामिल नहीं है।

अगर मैं गलत नहीं हूं, WebClientतो एक ही तरीके के कॉल में कई अलग-अलग अनुरोधों को अमूर्त करने में सक्षम है (उदाहरण के लिए 100 जारी प्रतिक्रियाओं को सही ढंग से संभालना, पुनर्निर्देशित करना, और पसंद करना)। मुझे संदेह है कि उपयोग किए बिना HttpWebRequestऔर HttpWebResponse, एक अलग स्थिति कोड उपलब्ध नहीं हो सकता है।

यह मेरे लिए होता है, यदि आप मध्यवर्ती स्थिति कोड में रुचि नहीं रखते हैं, तो आप सुरक्षित रूप से मान सकते हैं कि अंतिम स्थिति कोड 2xx (सफल) श्रेणी में है, अन्यथा, कॉल सफल नहीं होगी।

दुर्भाग्य से स्टेटस कोड ResponseHeadersडिक्शनरी में मौजूद नहीं है ।


2
ऐसा लगता है कि एकमात्र तरीका webrequest / response होगा
julio

1
यदि आप स्पष्ट रूप से कुछ अन्य 200 श्रृंखला संदेश (यानी 201 सृजित - देखें: w3.org/Protocols/rfc2616/rfc2616-sec10.html ) की तलाश कर रहे हैं तो एक समस्या आती है । : - / यह अच्छा होगा यदि यह स्पष्ट रूप से उपलब्ध हो, भले ही "इंटरमीडिएट" को छोड़ दिया गया हो।
नॉर्मन एच

1
@ नोर्मन, मैं असहमत नहीं हूं। ऐसा लगता है कि जब यह स्थिति कोड की बात आती है, तो WebClient थोड़ा अस्थिर होता है। चीयर्स!
kbrimington

87

आप जाँच सकते हैं कि क्या त्रुटि प्रकार की है WebExceptionऔर फिर प्रतिक्रिया कोड का निरीक्षण करें;

if (e.Error.GetType().Name == "WebException")
{
   WebException we = (WebException)e.Error;
   HttpWebResponse response = (System.Net.HttpWebResponse)we.Response;
   if (response.StatusCode==HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

या

try
{
    // send request
}
catch (WebException e)
{
    // check e.Status as above etc..
}

इस उत्तर के लिए बहुत बहुत धन्यवाद जो मुझे प्रतिक्रिया शीर्षलेख प्राप्त करने के लिए सही तरीके से इंगित करता है - WebException से, WebClient.ResponseHeaders से नहीं।
हांग

1
हाँ, सबसे अच्छा तरीका वास्तव में कोशिश डेटा को पकड़ने के ब्लॉक में पकड़ डेटा को पढ़ने और WebException को पकड़ने के लिए है
हेनरिक हर्ट्ज

2
मुझे यहाँ कुछ याद आ रहा है। न तो 'System.Exception' या 'System.Net.Exception' में 'Error' की परिभाषा है
ग्रेग वुड्स

13
कॉल सफल होने पर कोई अपवाद नहीं होगा (यानी 2xx या 3xx लौटाता है)। मूल पोस्टर 3xx की तलाश में था, मैं 204 की तलाश में हूं, अन्य लोग 201 की तलाश में हैं। यह पूछे गए सवाल का जवाब नहीं देता है।
शमौन ब्रुक

4
यह सुनिश्चित नहीं है कि मूल पोस्टर द्वारा लिखे जाने पर यह उत्तर अब तक कैसे उतारा गया: "क्या अपवाद कोड को प्राप्त करने का कोई तरीका है जब कोई अपवाद नहीं है?" मुझे लगता है अब नीचा दिखाने का कोई मतलब नहीं है।
मेंढक Pr1nce

33

प्रतिबिंब का उपयोग करने का एक तरीका है। यह .NET 4.0 के साथ काम करता है। यह एक निजी फ़ील्ड एक्सेस करता है और बिना संशोधनों के .NET के अन्य संस्करणों में काम नहीं कर सकता है।

मुझे पता नहीं है कि Microsoft ने इस क्षेत्र को एक संपत्ति के साथ उजागर क्यों नहीं किया।

private static int GetStatusCode(WebClient client, out string statusDescription)
{
    FieldInfo responseField = client.GetType().GetField("m_WebResponse", BindingFlags.Instance | BindingFlags.NonPublic);

    if (responseField != null)
    {
        HttpWebResponse response = responseField.GetValue(client) as HttpWebResponse;

        if (response != null)
        {
            statusDescription = response.StatusDescription;
            return (int)response.StatusCode;
        }
    }

    statusDescription = null;
    return 0;
}

2
एफडब्ल्यूआईडब्ल्यू, यह विंडोज फोन पर संभव नहीं है जो प्रतिबिंब के माध्यम से भी निजी सदस्यों तक पहुंचने की अनुमति नहीं देता है
ब्रेंडन

ध्यान दें कि BindingFlags को "System.Reflection का उपयोग करना" चाहिए
dlchambers

अच्छा है, लेकिन क्या सबस्टैटसकोड प्राप्त करने का एक तरीका है? उदाहरण के लिए 403.1 या 403.2?
रोनी तोवी

प्रतिक्रिया वस्तु में एक सबस्टैटसकोड गुण है। msdn.microsoft.com/en-us/library/…
दिमित्री एस।

29

यदि आप .net 4.0 (या कम) का उपयोग कर रहे हैं:

class BetterWebClient : WebClient
{
        private WebRequest _Request = null;

        protected override WebRequest GetWebRequest(Uri address)
        {
            this._Request = base.GetWebRequest(address);

            if (this._Request is HttpWebRequest)
            {
                ((HttpWebRequest)this._Request).AllowAutoRedirect = false;
            }

            return this._Request;
        } 

        public HttpStatusCode StatusCode()
        {
            HttpStatusCode result;

            if (this._Request == null)
            {
                throw (new InvalidOperationException("Unable to retrieve the status 
                       code, maybe you haven't made a request yet."));
            }

            HttpWebResponse response = base.GetWebResponse(this._Request) 
                                       as HttpWebResponse;

            if (response != null)
            {
                result = response.StatusCode;
            }
            else
            {
                throw (new InvalidOperationException("Unable to retrieve the status 
                       code, maybe you haven't made a request yet."));
            }

            return result;
        }
    }

यदि आप .Net 4.5.X या नया प्रयोग कर रहे हैं, तो HttpClient पर जाएँ :

var response = await client.GetAsync("http://www.contoso.com/");
var statusCode = response.StatusCode;

विंडोज फोन पर काम नहीं करता - GetWebResponse () केवल दो-पैरामिटर स्वाद में मौजूद है। अभी भी +1।
सेवा अलेक्सेयेव

दिलचस्प है कि यह काम नहीं करता है। खुशी है कि आपका जवाब चाल है!
एरिक फिलिप्स

मेरे लिए काम किया, जहां उच्चतर उत्तरों में प्रतिबिंब (.NET 4.5 विंडोज़ 7 और 10 ऐप) नहीं था
डेविड ने

9

एरिक का जवाब विंडोज फोन पर काम नहीं करता है। निम्नलिखित करता है:

class WebClientEx : WebClient
{
    private WebResponse m_Resp = null;

    protected override WebResponse GetWebResponse(WebRequest Req, IAsyncResult ar)
    {
        try
        {
            this.m_Resp = base.GetWebResponse(request);
        }
        catch (WebException ex)
        {
            if (this.m_Resp == null)
                this.m_Resp = ex.Response;
        }
        return this.m_Resp;
    }

    public HttpStatusCode StatusCode
    {
        get
        {
            if (m_Resp != null && m_Resp is HttpWebResponse)
                return (m_Resp as HttpWebResponse).StatusCode;
            else
                return HttpStatusCode.OK;
        }
    }
}

उपयोग करते समय कम से कम यह करता है OpenReadAsync; अन्य xxxAsyncतरीकों के लिए, सावधानीपूर्वक परीक्षण की अत्यधिक सिफारिश की जाएगी। कोड पाथ के साथ कहीं-कहीं फ्रेमवर्क GetWebResponse कहता है; सभी को करने की ज़रूरत है और प्रतिक्रिया ऑब्जेक्ट को कैश करें।

इस स्निपेट में फ़ॉलबैक कोड 200 है क्योंकि वास्तविक HTTP त्रुटियों - 500, 404, आदि को वैसे भी अपवाद के रूप में रिपोर्ट किया जाता है। इस चाल का उद्देश्य गैर-त्रुटि कोडों को कैप्चर करना है, मेरे विशिष्ट मामले में 304 (संशोधित नहीं)। इसलिए कमबैक मानता है कि यदि स्थिति कोड किसी तरह अनुपलब्ध है, तो कम से कम यह एक गैर-गलत है।


3

आपको उपयोग करना चाहिए

if (e.Status == WebExceptionStatus.ProtocolError)
{
   HttpWebResponse response = (HttpWebResponse)ex.Response;             
   if (response.StatusCode == HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

3
यह मतदान क्यों किया गया? ओपी स्पष्ट रूप से कहा गया है: However if the form is submitted successfully and no exception is thrown...
केनेथ लालकृष्ण

2

यह मैं WebClient कार्यक्षमता के विस्तार के लिए उपयोग करता हूं। StatusCode और StatusDescription में हमेशा सबसे हालिया प्रतिक्रिया कोड / विवरण होगा।

                /// <summary>
                /// An expanded web client that allows certificate auth and 
                /// the retrieval of status' for successful requests
                /// </summary>
                public class WebClientCert : WebClient
                {
                    private X509Certificate2 _cert;
                    public WebClientCert(X509Certificate2 cert) : base() { _cert = cert; }
                    protected override WebRequest GetWebRequest(Uri address)
                    {
                        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
                        if (_cert != null) { request.ClientCertificates.Add(_cert); }
                        return request;
                    }
                    protected override WebResponse GetWebResponse(WebRequest request)
                    {
                        WebResponse response = null;
                        response = base.GetWebResponse(request);
                        HttpWebResponse baseResponse = response as HttpWebResponse;
                        StatusCode = baseResponse.StatusCode;
                        StatusDescription = baseResponse.StatusDescription;
                        return response;
                    }
                    /// <summary>
                    /// The most recent response statusCode
                    /// </summary>
                    public HttpStatusCode StatusCode { get; set; }
                    /// <summary>
                    /// The most recent response statusDescription
                    /// </summary>
                    public string StatusDescription { get; set; }
                }

इस प्रकार आप एक पोस्ट कर सकते हैं और परिणाम प्राप्त कर सकते हैं:

            byte[] response = null;
            using (WebClientCert client = new WebClientCert())
            {
                response = client.UploadValues(postUri, PostFields);
                HttpStatusCode code = client.StatusCode;
                string description = client.StatusDescription;
                //Use this information
            }

इसने मेरे लिए बहुत अच्छा काम किया क्योंकि मैं प्रतिक्रिया कोड की तलाश में था। अच्छा समाधान!
बुराईफिश

ज्ञात हो कि [HttpClient के साथ विपरीत] 4xx और 5xx प्रतिक्रियाओं के परिणामस्वरूप एक WebException "प्रतिक्रिया = base.GetWebResponse (अनुरोध);" लाइन। आप अपवाद (यदि वे मौजूद हैं) से स्थिति और प्रतिक्रिया खींच सकते हैं।
मावरम

हाँ। आपको अभी भी सामान्य की तरह अपवादों को पकड़ना है। हालांकि, अगर कोई अपवाद नहीं है, तो यह उजागर करता है कि ओपी क्या चाहता था।
DFTR

1

बस किसी और को उपरोक्त वर्णित हैक के एफ # संस्करण की आवश्यकता होती है।

open System
open System.IO
open System.Net

type WebClientEx() =
     inherit WebClient ()
     [<DefaultValue>] val mutable m_Resp : WebResponse

     override x.GetWebResponse (req: WebRequest ) =
        x.m_Resp <- base.GetWebResponse(req)
        (req :?> HttpWebRequest).AllowAutoRedirect <- false;
        x.m_Resp

     override x.GetWebResponse (req: WebRequest , ar: IAsyncResult  ) =
        x.m_Resp <- base.GetWebResponse(req, ar)
        (req :?> HttpWebRequest).AllowAutoRedirect <- false;
        x.m_Resp

     member x.StatusCode with get() : HttpStatusCode = 
            if not (obj.ReferenceEquals (x.m_Resp, null)) && x.m_Resp.GetType() = typeof<HttpWebResponse> then
                (x.m_Resp :?> HttpWebResponse).StatusCode
            else
                HttpStatusCode.OK

let wc = new WebClientEx()
let st = wc.OpenRead("http://www.stackoverflow.com")
let sr = new StreamReader(st)
let res = sr.ReadToEnd()
wc.StatusCode
sr.Close()
st.Close()

-1

आप "क्लाइंट। रिस्पांसहेडर्स [..]" कॉल का उपयोग करने में सक्षम होना चाहिए , प्रतिक्रिया से सामान प्राप्त करने के उदाहरणों के लिए यह लिंक देखें


1
प्रतिसाद हेडर लौटाए गए सर्वर हेडर जैसे सर्वर, दिनांक, प्राग्म, आदि। लेकिन कोई स्थिति कोड (200,301,404 ...)
जूलियो

1
इसके बारे में क्षमा करें, यह देखकर थोड़ा आश्चर्य हुआ कि वापस नहीं लौटा।
पॉल हेडफील्ड

-1

आप इस कोड को WebException या OpenReadCompletedEventArgs.Error से HTTP स्थिति कोड प्राप्त करने का प्रयास कर सकते हैं। यह सिल्वरलाइट में भी काम करता है क्योंकि SL में WebExceptionStatus.ProtocolError परिभाषित नहीं है।

HttpStatusCode GetHttpStatusCode(System.Exception err)
{
    if (err is WebException)
    {
        WebException we = (WebException)err;
        if (we.Response is HttpWebResponse)
        {
            HttpWebResponse response = (HttpWebResponse)we.Response;
            return response.StatusCode;
        }
    }
    return 0;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.