在.net 4.5中使用 HttpClient 试图让 cookie 失去响应

我得到了下面这段成功运行的代码。我不知道怎么把饼干从回答中去掉。我的目标是希望能够在请求中设置 cookie,并从响应中获取 cookies。有什么想法吗?

private async Task<string> Login(string username, string password)
{
try
{
string url = "http://app.agelessemail.com/account/login/";
Uri address = new Uri(url);
var postData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password ", password)
};


HttpContent content = new FormUrlEncodedContent(postData);
var cookieJar = new CookieContainer();
var handler = new HttpClientHandler
{
CookieContainer = cookieJar,
UseCookies = true,
UseDefaultCredentials = false
};


var client = new HttpClient(handler)
{
BaseAddress = address
};




HttpResponseMessage response = await client.PostAsync(url,content);
response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
return body;
}
catch (Exception e)
{
return e.ToString();
}
}

以下是完整的答案:

HttpResponseMessage response = await client.PostAsync(url,content);
response.EnsureSuccessStatusCode();


Uri uri = new Uri(UrlBase);
var responseCookies = cookieJar.GetCookies(uri);
foreach (Cookie cookie in responseCookies)
{
string cookieName = cookie.Name;
string cookieValue = cookie.Value;
}
104153 次浏览

若要向请求添加 Cookie,请使用 CookieContainer.Add(uri, cookie)在请求之前填充 Cookie 容器。请求发出后,cookie 容器将自动填充来自响应的所有 cookie。然后可以调用 GetCookies ()来检索它们。

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

您可以通过给定的 URL 轻松获得 cookie 值。

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

如果你不能接触到 HttpClient也不能注射 CookieContainer还有一个选择。这个可以用。NET 核心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;
}

不是在所有情况下都可以将 httpClientHandler添加到 httpClient。例如,当您使用集成测试 testServer.CreateClient()或从 IHttpClientFactory注入 httpClient时。因此,我只是从头部读取值。

    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方法以完全匹配 Cookie 属性。