मैं HttpClient के HttpRequestMessage पर कुकी कैसे सेट करूं


247

मैं वेब एप का उपयोग एक पोस्टपॉइंट करने के लिए कर रहा हूं HttpClientजो एक HTTP कुकी के रूप में लॉगिन की आवश्यकता है जो एक खाते की पहचान करता है (यह केवल कुछ ऐसा है #ifdefजो रिलीज संस्करण से बाहर है)।

मैं कुकी कैसे जोड़ूं HttpRequestMessage?

जवाबों:


374

यहां बताया गया है कि आप अनुरोध के लिए कस्टम कुकी मान कैसे सेट कर सकते हैं:

var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("foo", "bar"),
        new KeyValuePair<string, string>("baz", "bazinga"),
    });
    cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
    var result = await client.PostAsync("/test", content);
    result.EnsureSuccessStatusCode();
}

2
हैंडलर को स्टेटमेंट का उपयोग करने से हटाया जा सकता है, यह तब निपटाया जाएगा जब http क्लाइंट को डिस्पोज किया जाएगा।
किमि

17
किमी सही है, लेकिन आपको एक उपयोग में अपने HttpClient को लपेटना नहीं चाहिए। aspnetmonsters.com/2016/08/2016-08/2016-httpclientwrong
रॉबर्ट

9
चेतावनी: यदि आप कई अनुरोधों को करने के लिए HttpClient के सिर्फ 1 उदाहरण का उपयोग करते हैं, तो कुकीजॉन्चर का उपयोग करने वाले कुकीज़ कैश्ड हो रहे हैं। क्या एक उपयोगकर्ता को दूसरे उपयोगकर्ता से कुकी प्राप्त करना खतरनाक है।
अकाज सूजा

31
"HttpClient को एक बार फिर से इंस्टेंट करने का इरादा है और एक एप्लिकेशन के पूरे जीवन में फिर से उपयोग किया जाता है। विशेष रूप से सर्वर अनुप्रयोगों में, हर अनुरोध के लिए एक नया HttpClient उदाहरण बनाने से भारी भार के तहत उपलब्ध सॉकेट की संख्या समाप्त हो जाएगी ..." यहां से: asp .net / वेब-एपीआई / ओवरव्यू / एडवांस्ड /…
सर्गेईट

4
@SergeyT जब एक ही संसाधन के लिए अलग-अलग सत्र कॉल करने की आवश्यकता होती है तो वह क्या करता है? :)
AgentFire

336

स्वीकार किए जाते हैं जवाब ज्यादातर मामलों में यह करने के लिए सही तरीका है। हालाँकि, कुछ स्थितियाँ ऐसी हैं जहाँ आप कुकी हेडर को मैन्युअल रूप से सेट करना चाहते हैं। आम तौर पर यदि आप एक "कुकी" शीर्षक सेट करते हैं तो इसे अनदेखा कर दिया जाता है, लेकिन ऐसा इसलिए है क्योंकि कुकीज़ के लिए HttpClientHandlerइसकी CookieContainerसंपत्ति का उपयोग करने में चूक है । आप की स्थापना करके फिर उस अक्षम करते हैं UseCookiesकरने के लिए falseआप मैन्युअल रूप से कुकी हेडर सेट कर सकते हैं और वे अनुरोध, जैसे में दिखाई देगा

var baseAddress = new Uri("http://example.com");
using (var handler = new HttpClientHandler { UseCookies = false })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var message = new HttpRequestMessage(HttpMethod.Get, "/test");
    message.Headers.Add("Cookie", "cookie1=value1; cookie2=value2");
    var result = await client.SendAsync(message);
    result.EnsureSuccessStatusCode();
}

44
मैं कई दिनों से एक त्रुटि का सामना कर रहा था जिसमें SendAsync के साथ भेजे गए अनुरोधों ने कुकी हेडर नहीं भेजा था; इसने मुझे यह महसूस करने में मदद की कि, जब तक आप हैंडलर में UseCookies = false सेट नहीं करते हैं, यह न केवल CookieContainer का उपयोग करेगा, बल्कि अनुरोध हेडरों में संग्रहीत किसी भी कुकी को चुपचाप अनदेखा कर देगा ! आपको बहुत - बहुत धन्यवाद!
फर्नांडो नीरा

14
यह उत्तर किसी को भी प्रॉक्सी के रूप में HttpClient का उपयोग करने की कोशिश करने के लिए बेहद मददगार है!
cchamberlain

3
अब यह कोशिश कर रहा है ... अगर यह काम करता है ... आप एक अच्छे राजभाषा 'कैनेडियन हग' के लायक हैं।
मैक्सिम रूलर 19

11
चेतावनी: यदि आप कई अनुरोधों को करने के लिए HttpClient के सिर्फ 1 उदाहरण का उपयोग करते हैं, तो कुकीजॉन्चर का उपयोग करने वाले कुकीज़ कैश्ड हो रहे हैं। क्या एक उपयोगकर्ता को दूसरे उपयोगकर्ता से कुकी प्राप्त करना खतरनाक है।
Acaz Souza

9
जब कोई व्यक्ति चुपचाप हारने के बजाय "कुकी" शीर्षक जोड़ने का प्रयास करता है, तो उस बेवकूफी वाली बात को एक अपवाद फेंक देना चाहिए। मेरे जीवन का एक घंटा मेरे लिए खर्च करें। समाधान के लिए धन्यवाद।
stmax

5

इस मुद्दे पर घंटों बिताने के बाद, ऊपर दिए गए किसी भी उत्तर ने मेरी मदद नहीं की, इसलिए मुझे एक बहुत उपयोगी उपकरण मिला।

सबसे पहले, मैंने विवरण में अपने वेब अनुरोधों का अध्ययन करने के लिए टेलरिक के फिडलर 4 का उपयोग किया

दूसरे, मैं फिडलर के लिए इस उपयोगी प्लगइन में आया:

https://github.com/sunilpottumuttu/FiddlerGenerateHttpClientCode

यह सिर्फ आपके लिए C # कोड जनरेट करेगा। एक उदाहरण था:

        var uriBuilder = new UriBuilder("test.php", "test");
        var httpClient = new HttpClient();


        var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uriBuilder.ToString());



        httpRequestMessage.Headers.Add("Host", "test.com");
        httpRequestMessage.Headers.Add("Connection", "keep-alive");
     //   httpRequestMessage.Headers.Add("Content-Length", "138");
        httpRequestMessage.Headers.Add("Pragma", "no-cache");
        httpRequestMessage.Headers.Add("Cache-Control", "no-cache");
        httpRequestMessage.Headers.Add("Origin", "test.com");
        httpRequestMessage.Headers.Add("Upgrade-Insecure-Requests", "1");
    //    httpRequestMessage.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        httpRequestMessage.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
        httpRequestMessage.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        httpRequestMessage.Headers.Add("Referer", "http://www.translationdirectory.com/");
        httpRequestMessage.Headers.Add("Accept-Encoding", "gzip, deflate");
        httpRequestMessage.Headers.Add("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8");
        httpRequestMessage.Headers.Add("Cookie", "__utmc=266643403; __utmz=266643403.1537352460.3.3.utmccn=(referral)|utmcsr=google.co.uk|utmcct=/|utmcmd=referral; __utma=266643403.817561753.1532012719.1537357162.1537361568.5; __utmb=266643403; __atuvc=0%7C34%2C0%7C35%2C0%7C36%2C0%7C37%2C48%7C38; __atuvs=5ba2469fbb02458f002");


        var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;

        var httpContent = httpResponseMessage.Content;
        string result = httpResponseMessage.Content.ReadAsStringAsync().Result;

ध्यान दें कि मुझे दो पंक्तियों पर टिप्पणी करनी थी क्योंकि यह प्लगइन अभी तक पूरी तरह से सही नहीं है लेकिन फिर भी इसने काम किया।

अस्वीकरण: मैं वैसे भी Telerik या प्लगइन लेखक द्वारा संबद्ध या समर्थन नहीं कर रहा हूँ।


2
यह अनिवार्य रूप से इस एक के रूप में एक ही जवाब है , इसका एकमात्र हिस्सा जो कुकीज़ के साथ करना है, वह हैडर का अंतिम जोड़। उस उत्तर में सभी चेतावनी पर ध्यान दें
जॉर्ज माउर

4

मेरे लिए सरल समाधान HttpRequestMessage ऑब्जेक्ट में कुकीज़ सेट करने के लिए काम करता है ।

protected async Task<HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken))
{
    requestMessage.Headers.Add("Cookie", $"<Cookie Name 1>=<Cookie Value 1>;<Cookie Name 2>=<Cookie Value 2>");

    return await _httpClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
}

ध्यान दें कि स्वीकृत उत्तर एक टन अधिक करता है और इससे बहुत अधिक किनारे की स्थिति को संभालता है। इसका उपयोग केवल http या स्कोप्ड कुकीज़, मल्टीवल्यू कुकीज़ आदि जैसी चीजों को करने के लिए किया जा सकता है। दूसरा सबसे ज्यादा मूल्यांकन किया गया उत्तर इस पद्धति का प्रस्ताव रखता है लेकिन बहुत अधिक संदर्भ और स्पष्टीकरण के साथ
जॉर्ज मौयर

@GeorgeMauer आप सही हो सकते हैं। दोनों ने "HttpClient (हैंडलर)" से httpClient का निर्माण किया। मेरे मामले में मैं httpClientPool से _httpClient बना रहा हूं। GetOrCreateHttpClient ()
वकार उल हक

1
लेकिन आप वास्तव में यह नहीं दिखाते हैं कि आपके उत्तर में और न ही अंतर या लाभों की व्याख्या करें (यह भी वास्तव में सवाल नहीं है, लेकिन मैं इसके बारे में चिंतित नहीं हूं)। मैं असभ्य होने की कोशिश नहीं कर रहा हूँ, इसका स्पष्ट होना महत्वपूर्ण है कि यह उत्तर किसके लिए मददगार होगा और दूसरों की मदद के लिए बेहतर नहीं होगा।
जॉर्ज माउर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.