在.net 4.5中试图通过HttpClient获取cookie而苦苦挣扎

Pet*_*ner 94 c# async-await dotnet-httpclient

我有以下代码可以成功运行.我无法弄清楚如何从响应中获取cookie.我的目标是希望能够在请求中设置cookie并从响应中获取cookie.思考?

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

这是完整的答案:

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

Des*_*tar 156

要向请求添加cookie,请在请求之前填充cookie容器CookieContainer.Add(uri, 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();
Run Code Online (Sandbox Code Playgroud)

  • 注意:在第一次通话中收到初始cookie后,当访问同一域中的任何页面时,cookie将自动发送,无需其他步骤. (7认同)
  • 如果 `httpclient` 是从 httpclient 工厂构建的,是否可以以相同的方式获取 cookie?即构建器方法添加到 services.AddHttpClient (2认同)

Ryt*_*s I 12

如果您无权访问HttpClient并且无法注入CookieContainer. 这适用于 .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;
}
Run Code Online (Sandbox Code Playgroud)

  • 刚刚尝试过,“var setCookieString = setCookie.Single();”可能应该更改,因为“setCookie”很可能有多个值,从而导致抛出异常。我最终添加了一个参数“string cookieName”,然后使用“setCookie.Single(x =&gt; x.StartsWith(cookieName));”。这仍然假设请求的 cookie 存在。 (2认同)

Alp*_*glu 6

您可以使用给定的 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)