.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呼び出しごとに個別の承認呼び出しを行う必要はありません。つまり、JSONを返すコールログ/ Home / GetDataがありますが、許可されている場合のみです。クライアント要求で、/ Home / GetDataが応答するようにCookieを追加します。それ以外の場合は、「403」が不正と表示されます。
Peter Kellner

Authorizationヘッダーをデフォルトのヘッダーとして設定することは、ほとんど同じくらい効果的で、もう少し標準的です。サーバーがクライアントに代わって自動的に認証ヘッダーを設定する方法はありません。
ダレルミラー

1
先端ダレルをありがとう。asp.netでどのように見えるかの例はありますか?モノタッチとWindowsストアアプリでこれに苦労しました。簡単な方法があったら幸いです。これは特にWindowsストアアプリで非同期で待機するのは面倒です。
Peter Kellner

回答:


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

^^ System.Linqは、.Cast <>メソッドを利用する場合にのみ必要です。Cookieの取得には必要ありませんが、これは自明です:)
MikeDub

httpclienthttpclientファクトリからビルドされた場合、同じ方法でcookieを取得できますか?つまり、services.AddHttpClientに追加されたビルダーメソッド
user3279954

get 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;
        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.