HttpClient'in HttpRequestMessage'ında nasıl çerez ayarlayabilirim?


247

HttpClientBir hesap tanımlayan bir HTTP tanımlama bilgisi biçiminde giriş gerektiren bir uç noktaya bir yazı yapmak için web api kullanmaya çalışıyorum (bu sadece #ifdefsürüm sürümü dışında düzenlenmiş bir şeydir ).

Adresine nasıl çerez ekleyebilirim HttpRequestMessage?

Yanıtlar:


374

İstek için nasıl özel çerez değeri ayarlayabileceğiniz aşağıda açıklanmıştır:

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
işleyici deyim kullanılarak kaldırılabilir, http istemcisi atıldığında imha edilir.
Kimi

17
Kimi doğrudur, ancak HttpClient'inizi bir kullanımda sarmamalısınız. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Robert McLaws

9
DİKKAT: Birden fazla istekte bulunmak için yalnızca 1 HttpClient örneği kullanırsanız, CookieContainer kullanan çerezler önbelleğe alınır. Kullanıcı için çerezi başka bir kullanıcıdan almak tehlikeli.
Acaz Souza

31
"HttpClient'in bir kez başlatılması ve bir uygulamanın ömrü boyunca yeniden kullanılması amaçlanmıştır. Özellikle sunucu uygulamalarında, her istek için yeni bir HttpClient örneği oluşturmak, ağır yükler altında kullanılabilen soket sayısını tüketecektir ..." Buradan: asp .net / web-api / genel bakış / gelişmiş /…
SergeyT

4
@SergeyT, aynı kaynağa ayrı oturum çağrıları yapması gerektiğinde ne yapar? :)
AgentFire

337

Kabul edilen cevap , çoğu durumda bunu yapmanın doğru yoludur. Ancak, çerez başlığını manuel olarak ayarlamak istediğiniz bazı durumlar vardır. Normalde bir "Çerez" üstbilgisi ayarlarsanız, bu yoksayılır, ancak bunun nedeni HttpClientHandlervarsayılan olarak CookieContainerçerezler için özelliğini kullanmasıdır . Eğer ayarlayarak o devre dışı bırakırsanız UseCookiesiçin falsemanuel çerez başlıklarını ayarlayabilirsiniz siz ve onlar istek, örneğin görünecektir

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
Birkaç gündür SendAsync ile gönderilen isteklerin çerez başlığını göndermediği bir hatayı takip ediyorum; Bu, Handler'de UseCookies = false ayarlamazsanız, yalnızca CookieContainer'ı kullanmanın yanı sıra istek başlıklarında saklanan tüm Cookie'leri sessizce göz ardı edeceğini anlamama yardımcı oldu ! Çok teşekkür ederim!
Fernando Neira

14
Bu yanıt, HttpClient'i proxy olarak kullanmaya çalışan herkes için son derece yararlıdır!
cchamberlain

3
Şimdi denemek ... işe yarıyorsa ... iyi bir Kanadalı sarılmayı hak ediyorsun.
Maxime Rouiller

11
DİKKAT: Birden fazla istekte bulunmak için yalnızca 1 HttpClient örneği kullanırsanız, CookieContainer kullanan çerezler önbelleğe alınır. Kullanıcı için çerezi başka bir kullanıcıdan almak tehlikeli.
Acaz Souza

9
Birisi sessizce kaybetmek yerine bir "Çerez" başlığı eklemeye çalıştığında bu aptalca şey bir istisna atmalıdır. Bana hayatımın bir saatine mal oldu. Çözüm için teşekkürler.
stmax

5

Bu konuda saatler geçirdikten sonra, yukarıdaki cevapların hiçbiri bana yardımcı olmadı, bu yüzden gerçekten kullanışlı bir araç buldum.

İlk olarak, Web İsteklerimi ayrıntılı olarak incelemek için Telerik'in Fiddler 4'ü kullandım

İkincisi, Fiddler için bu yararlı eklentiyle karşılaştım:

https://github.com/sunilpottumuttu/FiddlerGenerateHttpClientCode

Sadece sizin için C # kodunu üretecektir. Bir örnek:

        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;

Bu eklenti henüz tamamen mükemmel olmadığı için iki satır yorum yapmak zorunda olduğumu unutmayın, ancak yine de işi yaptı.

YASAL UYARI: Zaten Telerik veya eklentinin yazarı tarafından ilişkilendirilmiyorum veya onaylanmıyorum.


2
Bu temelde aynı cevaptır bunun gibi , çerezler ile ilgisi var bunun sadece bir parçasıdır, bir başlığın son ektir. Bu cevaptaki tüm uyarıları not edin
George Mauer

4

Benim için basit bir çözüm HttpRequestMessage nesnesinde çerezleri ayarlamak için çalışır .

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

Kabul edilen cevabın bir ton daha fazla yaptığını ve bundan daha fazla kenar koşulunu ele aldığını unutmayın . En yüksek ikinci oy alan cevap bu kadar ama çok daha bağlam ve açıklama ile aynı yöntemi önermektedir http sadece kapsamlı kurabiye veya multivalue çerezler, vs vs gibi şeyler için kullanılabilir
George Mauer

@ GeorgeMauer haklı olabilirsiniz. Her ikisi de "HttpClient (işleyici)" den httpClient oluşturur. Benim durumumda httpClientPool.GetOrCreateHttpClient ()
Waqar UlHaq

1
Ama aslında cevabınızda ne farkı ne de faydaları açıklamıyorsunuz (aslında soru da değil, ama bunun için endişelenmiyorum). Kaba olmaya çalışmıyorum, bu cevabın kim için yararlı olacağını açıklığa kavuşturmak sadece diğerlerine daha iyi yardımcı olmayacak.
George Mauer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.