Gặp khó khăn khi cố gắng loại bỏ cookie khỏi phản hồi với HttpClient trong .net 4.5


107

Tôi có mã sau hoạt động thành công. Tôi không thể tìm ra cách lấy cookie ra khỏi phản hồi. Mục tiêu của tôi là tôi muốn có thể đặt cookie trong yêu cầu và lấy cookie ra khỏi phản hồi. Suy nghĩ?

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

Đây là câu trả lời đầy đủ:

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

Vì tò mò, tôi có thể hỏi tại sao bạn muốn đọc cookie trên máy khách? Sự hiểu biết của tôi là cookie được sử dụng để gửi thông tin đến máy chủ, không phải để trả lại thông tin.
Darrel Miller

Tôi sử dụng cookie được trả về trên các lệnh gọi trả về JSON để tôi không phải thực hiện lệnh gọi ủy quyền riêng cho mỗi lệnh gọi JSON. Nghĩa là, tôi có nhật ký cuộc gọi / Home / GetData trả về JSON nhưng chỉ khi được ủy quyền. Theo yêu cầu của khách hàng, tôi thêm cookie để / Home / GetData sẽ phản hồi. Nếu không nó sẽ báo "403" trái phép.
Peter Kellner

Đặt tiêu đề ủy quyền làm tiêu đề mặc định gần như hiệu quả và tiêu chuẩn hơn một chút. Không có cách nào để máy chủ tự động đặt tiêu đề xác thực thay mặt cho máy khách.
Darrel Miller

1
cảm ơn cho lời khuyên Darrel. Bạn có bất kỳ ví dụ nào về những gì có thể trông giống như trong asp.net không? Tôi đã vật lộn với điều này cho cảm ứng đơn của mình và bây giờ là ứng dụng cửa hàng windows của tôi. Tôi sẽ rất vui nếu có một cách đơn giản. Đây là một khó khăn, đặc biệt là với không đồng bộ và đang chờ đợi bây giờ trên các ứng dụng cửa hàng windows.
Peter Kellner

Câu trả lời:


170

Để thêm cookie vào một yêu cầu, hãy điền vùng chứa cookie trước yêu cầu với CookieContainer.Add(uri, cookie). Sau khi yêu cầu được thực hiện, vùng chứa cookie sẽ tự động được điền vào với tất cả các cookie từ phản hồi. Sau đó, bạn có thể gọi GetCookies () để truy xuất chúng.

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
Lưu ý: Sau khi nhận được cookie ban đầu trong lần gọi đầu tiên, khi truy cập bất kỳ trang nào từ cùng một miền, cookie sẽ được gửi tự động, không cần thực hiện thêm bước nào.
Jahmic

Bạn phải thêm "using System.linq;"
Cabuxa.Mapache

^^ System.Linq chỉ cần thiết nếu bạn muốn sử dụng các .Cast <> phương pháp, nó không cần thiết cho việc thu hồi cookie, nhưng điều này nên tự giải thích :)
MikeDub

Có thể lấy cookie theo cách tương tự nếu httpclientđược xây dựng từ nhà máy httpclient không? tức là phương pháp xây dựng thêm vào services.AddHttpClient
user3279954

trên get Async, chúng tôi đã tạo tham chiếu đến "google.com", tại sao chúng tôi cần khai báo một URI với tham chiếu đến nó một lần nữa?
Malcolm Salvador

7

Có một giải pháp thay thế nếu bạn không có quyền truy cập HttpClientvà không thể tiêm CookieContainer. Điều này hoạt động trong .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
Rực rỡ và thô sơ nhưng chỉ là những gì tôi cần ... Làm tốt lắm, cảm ơn.
Vedran Mandić

5

Bạn có thể dễ dàng nhận được giá trị cookie với URL đã cho.

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;
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.