如何从HttpResponseMessage读取cookie?

mmh*_*h18 18 c# cookies asp.net-web-api dotnet-httpclient

这是我最近的代码:

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;
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 18

我在这里的许多答案中遇到的问题是使用不推荐CookieContainer使用的短期HttpClient对象

相反,您可以简单地"Set-Cookie"从响应中读取标头:

// 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;
Run Code Online (Sandbox Code Playgroud)

  • 一旦我们得到了“cookies”字符串,有没有一种干净的方法来获取特定的cookie值?必须解析字符串来提取实际的 cookie 值,感觉有点笨拙。我认为 .Net 中可能有一个辅助方法来处理它,但我的大部分研究都回到了 CookieContainer,在重用 HttpClient 实例时我们无法使用它。 (2认同)
  • KeyValuePair 不可为空 (2认同)

Rag*_*lly 8

试试这个:

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>();
Run Code Online (Sandbox Code Playgroud)

  • 另外,如果您使用 HttpClient 作为许多并行请求的共享实例(建议使用 https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ ),请注意处理程序中的 cookie 可能会属于不同的并行响应,而不是您刚刚收到的响应。除非您对每个请求进行一些锁定以避免此类 cookie 竞争条件。 (3认同)

Mar*_*oVW 6

建立在Daniel 的答案另一个问题的答案之上,这将是从 HTTP 响应中读取 cookie 的简单方法。

// 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;
Run Code Online (Sandbox Code Playgroud)


Alp*_*glu 5

这是您获取 cookie 列表所需要的;

    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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果您只需要一个 cookie 值,方法如下

 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;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)