43

This is my recent code:

HttpClient authClient = new HttpClient(); authClient.BaseAddress = new Uri("http://localhost:4999/test_db/_session"); authClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var user = new LoginUserSecretModel { name = userKey, password = loginData.Password, }; HttpResponseMessage authenticationResponse = authClient.PostAsJsonAsync("", user).Result; 
1
  • 4
    Anyway, don't use Result. Use await authClient.PostAsJsonAsync() instead. Commented Mar 24, 2015 at 3:58

4 Answers 4

36

The issue I have with many of the answers here is that using CookieContainer uses short-lived HttpClient objects which is not recommended.

Instead, you can simply read the "Set-Cookie" header from the response:

// httpClient is long-lived and comes from a IHttpClientFactory HttpResponseMessage response = await httpClient.GetAsync(uri); IEnumerable<string> cookies = response.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; 

If the "Set-Cookie" header is not present, cookies will be null.

Sign up to request clarification or add additional context in comments.

6 Comments

Once we get the "cookies" string, is there a clean way to obtain a specific cookie value? It feels a bit clunky to have to parse the string to extract the actual cookie value. I assume there's probably be a helper method in .Net to handle it, but most of my researches circle back to CookieContainer which we can't use when reusing our HttpClient instance.
Best answer if a person wants to have both a response and the cookies from that response. In my humble opinion, parsing the string is trivial.
KeyValuePair is not nullable
Small technicality: KeyValuePair<string, IEnumerable<string>> cannot be tested for null so ?.Value is a syntax error.
Thanks @cubesnyc and @Hari, I've fixed the answer and added a line describing what happens if there is no "Set-Cookie" header.
|
17

Try this:

CookieContainer cookies = new CookieContainer(); HttpClientHandler handler = new HttpClientHandler(); handler.CookieContainer = cookies; HttpClient authClient = new HttpClient(handler); var uri = new Uri("http://localhost:4999/test_db/_session"); authClient.BaseAddress = uri; authClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var user = new LoginUserSecretModel { name = userKey, password = loginData.Password, }; HttpResponseMessage authenticationResponse = authClient.PostAsJsonAsync("", user).Result; var responseCookies = cookies.GetCookies(uri).Cast<Cookie>(); 

6 Comments

thank you for your answer .... but "cookie" count was 0 and nothing containing when i get HttpResponseMassage.
Are you sure cookies are being set?
yes i already set, i found the cookies are in authenticationResponse.headers.
Are the cookies secure? See here: stackoverflow.com/questions/14681144/…
Also, if you are using HttpClient as a shared instance for many parallel requests (as it is recommended aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong ) , be aware that cookies in the handler might belong to a different parallel response, not the one you just received. Unless you do some locking for every request to avoid such cookie race conditions.
|
7

This is what you need to get a list of cookies;

 private async Task<List<Cookie>> GetCookies(string url, string cookieName) { var cookieContainer = new CookieContainer(); var uri = new Uri(url); using (var httpClientHandler = new HttpClientHandler { CookieContainer = cookieContainer }) { using (var httpClient = new HttpClient(httpClientHandler)) { await httpClient.GetAsync(uri); List<Cookie> cookies = cookieContainer.GetCookies(uri).Cast<Cookie>().ToList(); return cookies; } } } 

and if you need only one cookie value here's how

 private async Task<string> GetCookieValue(string url) { var cookieContainer = new CookieContainer(); var uri = new Uri(url); using (var httpClientHandler = new HttpClientHandler { CookieContainer = cookieContainer }) { using (var httpClient = new HttpClient(httpClientHandler)) { await httpClient.GetAsync(uri); var cookie = cookieContainer.GetCookies(uri).Cast<Cookie>().FirstOrDefault(x => x.Name == cookieName); return cookie?.Value; } } } 

Comments

7

Building on top of Daniel's answer and this answer to another question, this would be an easy way to read the cookies from an HTTP response.

// httpClient is long-lived and comes from a IHttpClientFactory HttpResponseMessage response = await httpClient.GetAsync(uri); CookieContainer cookies = new CookieContainer(); foreach (var cookieHeader in response.Headers.GetValues("Set-Cookie")) cookies.SetCookies(uri, cookieHeader); string cookieValue = cookies.GetCookies(uri).FirstOrDefault(c => c.Name == "MyCookie")?.Value; 

1 Comment

This worked better for me because I have a shared HttpClient instance and didn't need to work with cookies on all of the endpoints.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.