WebClient वर्ग के साथ CookieContainer का उपयोग करना


148

मैंने पहले HttpWebRequest और HttpWebResponse सत्रों के साथ CookieContainer का उपयोग किया है, लेकिन अब, मैं इसे एक WebClient के साथ उपयोग करना चाहता हूं। जहां तक ​​मैं समझता हूं, कोई अंतर्निहित पद्धति नहीं है जैसे कि HttpWebRequests ( request.CookieContainer) के लिए है। मैं एक कुकी में वेबक्लाइंट से कुकी कैसे एकत्र कर सकता हूं?

मैं इस के लिए googled और निम्नलिखित नमूना पाया :

public class CookieAwareWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}

क्या यह करने का सबसे अच्छा तरीका है?


1
मेरे दृष्टिकोण m_containerसे कभी सेट नहीं है !? क्या यह हमेशा खाली है?
C4d

मेरा मानना ​​है कि HttpWebRequest वर्ग अपने आंतरिक क्षेत्र CookieContainer का उपयोग करके m_container वर्ग को आवश्यकतानुसार संशोधित करता है।
हार्ट वेयर

यह आप सभी की जरूरत है! प्रतिक्रियाओं से कुकीज़ स्वचालित रूप से कंटेनर में जुड़ जाएंगी।
लायनेलो

जवाबों:


69

हाँ। IMHO, GetWebRequest () को ओवरराइड करना WebClient की सीमित कार्यक्षमता का सबसे अच्छा समाधान है। इससे पहले कि मैं इस विकल्प के बारे में जानता, मैंने बहुत ही दर्दनाक कोड HttpWebRequest लेयर में लिखा क्योंकि WebClient लगभग, लेकिन काफी नहीं, वही किया जो मुझे चाहिए था। व्युत्पत्ति बहुत आसान है।

एक अन्य विकल्प नियमित WebClient वर्ग का उपयोग करना है, लेकिन अनुरोध करने से पहले मैन्युअल रूप से कुकी हेडर को पॉप्युलेट करें और फिर प्रतिक्रिया पर सेट-कुकीज़ हेडर को बाहर निकालें। CookieContainer वर्ग पर सहायक विधियाँ हैं जो इन हेडरों को बनाना और बनाना आसान बनाती हैं: CookieContainer.SetCookies()और CookieContainer.GetCookieHeader()क्रमशः।

मैं पूर्व दृष्टिकोण को पसंद करता हूं क्योंकि यह कॉलर के लिए आसान है और दूसरे विकल्प की तुलना में कम दोहराव वाले कोड की आवश्यकता होती है। इसके अलावा, व्युत्पत्ति दृष्टिकोण कई एक्स्टेंसिबिलिटी परिदृश्यों (जैसे कुकीज़, परदे के पीछे, आदि) के लिए उसी तरह काम करता है।


118
 WebClient wb = new WebClient();
 wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");

टिप्पणियाँ से

आप "somecookie" के स्थान पर कुकी के नाम और मूल्य को कैसे प्रारूपित करेंगे?

wb.Headers.Add(HttpRequestHeader.Cookie, "cookiename=cookievalue"); 

कई कुकीज़ के लिए:

wb.Headers.Add(HttpRequestHeader.Cookie, 
              "cookiename1=cookievalue1;" +
              "cookiename2=cookievalue2");

आप "somecookie" के स्थान पर कुकी के नाम और मूल्य को कैसे प्रारूपित करेंगे?
नील एन

11
@ नील एन: wb.Headers.Add (HttpRequestHeader.Cookie, "cookiename = cookorpue"); कई कुकीज़ के लिए: wb.Headers.Add (HttpRequestHeader.Cookie, "cookiename1 = cook मध्यकालीनue1; cookiename2 = cook मध्यकालीनue2");
इयान केम्प

46

यह केवल आपके द्वारा पाया गया लेख का विस्तार है।


public class WebClientEx : WebClient
{
    public WebClientEx(CookieContainer container)
    {
        this.container = container;
    }

    public CookieContainer CookieContainer
        {
            get { return container; }
            set { container= value; }
        }

    private CookieContainer container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest r = base.GetWebRequest(address);
        var request = r as HttpWebRequest;
        if (request != null)
        {
            request.CookieContainer = container;
        }
        return r;
    }

    protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
    {
        WebResponse response = base.GetWebResponse(request, result);
        ReadCookies(response);
        return response;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        ReadCookies(response);
        return response;
    }

    private void ReadCookies(WebResponse r)
    {
        var response = r as HttpWebResponse;
        if (response != null)
        {
            CookieCollection cookies = response.Cookies;
            container.Add(cookies);
        }
    }
}

3
इसने अच्छी तरह से @Pavel पर काम किया, हालाँकि आप इस उत्तर को बेहतर बना सकते हैं कि वर्ग की विशेषताओं का उपयोग कैसे करें, विशेष रूप से सेटिंग और उस पर कुकीज़ प्राप्त करना।
कॉरगलोर

विस्तार के लिए Thx। इसके उपयोग के लिए मैं सार्वजनिक CookieContainer CookieContainer {get {return _container; } सेट {_कंटेनर = मूल्य; }}
इगोर शुबिन

1
@IgorShubin आपको फ़ील्ड के readonlyसंशोधक को निकालना होगा container, अन्यथा आप इसे संपत्ति में सेट नहीं कर सकते। मैंने कोड को संशोधित किया।
पहाड़ी

1
क्या आपको Set-Cookieप्रतिक्रिया शीर्ष लेख की जांच नहीं करनी चाहिए ReadCookies?
अचिल्स

2
आप वास्तव में जरूरत नहीं है GetWebResponseऔर ReadCookies, के बाद से कुकीज़ स्वचालित रूप से कंटेनर में जोड़ दी जाती।
लायनेलो

15

HttpWebRequest इसे निर्दिष्ट किए गए CookieContainer को संशोधित करता है। लौटी कुकीज़ को संसाधित करने की कोई आवश्यकता नहीं है। बस अपने कुकी कंटेनर को हर वेब अनुरोध पर असाइन करें।

public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; } = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest request = base.GetWebRequest(uri);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = CookieContainer;
        }
        return request;
    }
}

6

मुझे लगता है कि वहाँ क्लीनर तरीका है जहाँ आपको एक नया वेबक्लिअर नहीं बनाना होगा (और यह 3 पार्टी लाइब्रेरी के साथ भी काम करेगा)

internal static class MyWebRequestCreator
{
    private static IWebRequestCreate myCreator;

    public static IWebRequestCreate MyHttp
    {
        get
        {
            if (myCreator == null)
            {
                myCreator = new MyHttpRequestCreator();
            }
            return myCreator;
        }
    }

    private class MyHttpRequestCreator : IWebRequestCreate
    {
        public WebRequest Create(Uri uri)
        {
            var req = System.Net.WebRequest.CreateHttp(uri);
            req.CookieContainer = new CookieContainer();
            return req;
        }
    }
}

अब आपको बस इतना करना है कि आप किन डोमेन का उपयोग करना चाहते हैं:

    WebRequest.RegisterPrefix("http://example.com/", MyWebRequestCreator.MyHttp);

इसका मतलब है कि कोई भी वेबरेक्स्ट जो example.com पर जाता है, अब आपके कस्टम वेबरेक्स्ट क्रिएटर का उपयोग करेगा, जिसमें मानक वेबक्लेयर भी शामिल है। इस दृष्टिकोण का मतलब है कि आपको सभी कोड को छूने की आवश्यकता नहीं है। आप बस एक बार रजिस्टर उपसर्ग को बुलाते हैं और इसके साथ किया जाता है। आप हर जगह सब कुछ चुनने के लिए "http" उपसर्ग के लिए पंजीकरण भी कर सकते हैं।


मैं पिछले कुछ वाक्यों के बारे में निश्चित नहीं हूँ; डॉक्स कहते हैं: "HttpWebRequest वर्ग डिफ़ॉल्ट रूप से HTTP और HTTPS योजनाओं के लिए सेवा अनुरोध करने के लिए पंजीकृत किया गया है इन योजनाओं असफल हो जायेगी के लिए एक अलग WebRequest वंशज रजिस्टर करने के लिए प्रयास।।"
हेरोहार्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.