.net 4.5中使用HttpClient努力使Cookie脱颖而出


107

我有以下代码可以成功运行。我不知道如何从响应中获取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();
    }
}

这是完整的答案:

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

出于好奇,我能否问您为什么要在客户端上读取Cookie?我的理解是cookie用于将信息发送到服务器,而不是用于返回信息。
Darrel Miller

我在返回JSON的调用上使用返回的cookie,因此不必为每个JSON调用单独进行授权。也就是说,我有一个呼叫日志/ Home / GetData,它仅在获得授权的情况下返回JSON。应客户要求,我添加cookie,以便/ Home / GetData响应。否则会说“ 403”未授权。
彼得·凯尔纳

将授权标头设置为默认标头几乎一样有效,并且更加标准。服务器无法代表客户端自动设置auth标头。
Darrel Miller 2012年

1
感谢小费Darrel。您在asp.net中有什么例子吗?我为单点触控以及现在的Windows应用商店应用而为此苦苦挣扎。如果有一个简单的方法,我会很高兴。这是一个痛苦,特别是对于Windows应用商店上的async和await现在。
彼得·凯尔纳

Answers:


170

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

8
注意:在第一个调用中收到初始cookie后,从同一域访问任何页面时,这些cookie将自动发送,无需其他步骤。
Jahmic

您必须添加“ using System.linq;”
Cabuxa.Mapache

^^仅当您希望使用.Cast <>方法时才需要System.Linq,它对于cookie检索不是必需的,但这应该是不言而喻的:)
MikeDub

如果httpclient是从httpclient工厂构建的,是否可以以相同的方式获取Cookie ?即生成器方法添加到services.AddHttpClient
user3279954 '19

在获取Async时,我们已经引用了“ google.com”,为什么我们需要再次声明带有引用的URI?
马尔科姆·萨尔瓦多

7

如果您无权访问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;
}

1
辉煌而原始,但正是我所需要的...干得好,谢谢。
VedranMandić

5

您可以使用给定的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;
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.