Намагаються вийти з файлу cookie у відповідь з HttpClient в .net 4.5


107

У мене є такий код, який успішно працює. Я не можу зрозуміти, як отримати печиво з відповіді. Моя мета полягає в тому, щоб я хотів мати можливість встановити файли 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 використовуються для надсилання інформації на сервер, а не для повернення інформації.
— Даррел Міллер

Я використовую повернене cookie для дзвінків, які повертають JSON, так що мені не потрібно робити окремий виклик авторизації для кожного дзвінка JSON. Тобто, у мене є журнал викликів / Головна / GetData, який повертає JSON, але лише за умови дозволу. На запит клієнта я додаю файл cookie, щоб / Home / GetData відповів. Інакше воно скаже "403" несанкціоновано.
— Пітер Кельнер

Встановлення заголовка авторизації як заголовка за замовчуванням майже настільки ж ефективно та трохи стандартніше. Просто сервер не може автоматично встановити заголовок auth від імені клієнта.
— Даррел Міллер

1
дякую за пораду Даррел. Чи є у вас приклади того, як це може виглядати на asp.net? Я боровся з цим за свій монотух і тепер додаток для магазину Windows. Я був би радий, якби був простий спосіб. Це біль, особливо з асинхронізацією та очікуванням зараз на додатках Windows Store.
— Пітер Келнер

Відповіді:


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 надсилаються автоматично, без додаткових кроків не потрібно.
— Яхміч

Ви повинні додати "за допомогою System.linq;"
— Cabuxa.Mapache

^^ System.Linq потрібен лише в тому випадку, якщо ви хочете використовувати метод .Cast <>, для пошуку файлів cookie він не потрібен, але це повинно бути роз'яснювальним :)
— MikeDub

Чи можливо отримати файли cookie однаковим чином, якщо httpclientвін створений на заводі httpclient? тобто доданий до сервісів метод
— builder.AddHttpClient

ми отримали посилання на "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
Блискуче і сире, але саме те, що мені потрібно ... Гарна робота, дякую.
— Ведран Мандич

5

Ви можете легко отримати значення файлу cookie за вказаною URL-адресою.

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;
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.