Struggling trying to get cookie out of response with HttpClient in .net 4.5
To add cookies to a request, populate the cookie container before the request with CookieContainer.Add(uri, cookie)
. After the request is made the cookie container will automatically be populated with all the cookies from the response. You can then call GetCookies() to retreive them.
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = client.GetAsync("http://google.com").Result;
Uri uri = new Uri("http://google.com");
IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
Console.WriteLine(cookie.Name + ": " + cookie.Value);
Console.ReadLine();
Not in every case you can add httpClientHandler
to httpClient
. For example, when you use integration tests testServer.CreateClient()
or inject httpClient
from IHttpClientFactory
. So, I have simply read values from header.
public static List<Cookie> GetCookies(this HttpResponseMessage message)
{
message.Headers.TryGetValues("Set-Cookie", out var cookiesHeader);
var cookies = cookiesHeader.Select(cookieString => CreateCookie(cookieString)).ToList();
return cookies;
}
private static Cookie CreateCookie(string cookieString)
{
var properties = cookieString.Split(';', StringSplitOptions.TrimEntries);
var name = properties[0].Split("=")[0];
var value = properties[0].Split("=")[1];
var path = properties[2].Replace("path=", "");
var cookie = new Cookie(name, value, path)
{
Secure = properties.Contains("secure"),
HttpOnly = properties.Contains("httponly"),
Expires = DateTime.Parse(properties[1].Replace("expires=", ""))
};
return cookie;
}
CreateCookie
method may be modified to exactly match your cookie properties.
You can easily get a cookie value with the given URL.
private async Task<string> GetCookieValue(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);
var cookie = cookieContainer.GetCookies(uri).Cast<Cookie>().FirstOrDefault(x => x.Name == cookieName);
return cookie?.Value;
}
}
}
There's alternative if you don't have access to the HttpClient
and can't inject the CookieContainer
. This works in .NET Core 2.2:
private string GetCookie(HttpResponseMessage message)
{
message.Headers.TryGetValues("Set-Cookie", out var setCookie);
var setCookieString = setCookie.Single();
var cookieTokens = setCookieString.Split(';');
var firstCookie = cookieTokens.FirstOrDefault();
var keyValueTokens = firstCookie.Split('=');
var valueString = keyValueTokens[1];
var cookieValue = HttpUtility.UrlDecode(valueString);
return cookieValue;
}