简体   繁体   中英

ASP.NET Core 2 get cookies from HttpResponseMessage

currently I am working on a Project written with ASP.NET Core 2 and I am trying to get a JSON file from a third party website. The problem is that this website requires a few cookies in order to retrieve data from it. I implemented a typed HttpClient in my Startup.cs file like this:

    services.AddHttpClient<IMyClient, MyClient>().ConfigurePrimaryHttpMessageHandler(() =>
    {
        return new HttpClientHandler()
        {
            UseCookies = true,
            UseDefaultCredentials = true,
            CookieContainer = new CookieContainer()
        };
    });

Is there any way of accessing the CookieContainer to use the CookieContainer.GetCookies() method, so that I can copy various cookies like the Session Cookie and some verification tokens from the HttpResponseMessage?

Sorry if I am making something wrong, this is my first post.

EDIT

Got it to work by adding a HttpMessageHandler in the Request Pipeline

services.AddHttpClient<IMyHttpClient, MyHttpClient>()
                    .AddHttpMessageHandler<MyMessageHandler>();

and edit the http header information in the HttpMessageHandler

public class MyMessageHandler : DelegatingHandler
{
    private readonly CookieContainer _cookies;

    public MyMessageHandler()
    {
        _cookies = new CookieContainer();
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage message, CancellationToken cancellationToken)
    {
        try
        {
            if (_cookies.Count == 0 && message.RequestUri.Host.Contains("example.com"))
            {
                // Simulate the Request
                var getCookieMesssage = new HttpRequestMessage()
                {
                    RequestUri = new Uri("http://www.example.com/"),
                    Content = message.Content,
                    Method = HttpMethod.Get,
                };

                // Simulate User Agent
                foreach(var agent in message.Headers.UserAgent)
                {
                    getCookieMesssage.Headers.UserAgent.Add(agent);
                }

                var testResponse = await base.SendAsync(getCookieMesssage, cancellationToken);

                if (testResponse.Headers.TryGetValues("Set-Cookie", out var newCookies))
                {
                    foreach (var item in SetCookieHeaderValue.ParseList(newCookies.ToList()))
                    {
                        var uri = new Uri(message.RequestUri, item.Path.Value);

                        // Add parsed cookies to CookieContainer
                        _cookies.Add(uri, new Cookie(item.Name.Value, item.Value.Value, item.Path.Value));
                    }
                }
                // Add parsed cookies to the header of the HttpRequestMessage
                message.Headers.Add("Cookie", _cookies.GetCookieHeader(message.RequestUri));
            }
            // get response
            var response = await base.SendAsync(message, cancellationToken).ConfigureAwait(false);

            return response;
        }catch(Exception ex)
        {
            throw ex;
        }

    }

}

This approach gets all cookies from the Set-Cookie header and adds it to the Cookie header of the request.

If MyClient is a custom implementation of HttpClient you can overload the constructor to store a reference to the HttpClientHandler :

public MyClient(HttpMessageHandler handler) 
       : base(handler)
{
    Handler = handler;
}

public MyClient(HttpMessageHandler handler, bool disposeHandler) 
       : base(handler, disposeHandler )
    Handler = handler;
)

public HttpMessageHandler Handler { get; }

The answer from your edit isn't clear so I've summarised it here. Also, there is no need for explicitly setting HttpClientHandler.UseCookies = true or for having a CookieContainer .

To get the cookies from the call, you can simply read the "Set-Cookie" response header:

HttpResponseMessage response = await httpClient.GetAsync(uri);
IEnumerable<string> cookies = response.Headers.SingleOrDefault(header => header.Key == "Set-Cookie")?.Value;
$.ajax({
            url: "https://localhost:44330/api/Records",
            type: 'POST',
            contentType:"application/json; charset=utf-8",
               dataType:"json",
            data: JSON.stringify(formdata),
            // Fetch the stored token from localStorage and set in the header
           headers: {"Authorization":'Bearer '+data.data.token},
            success: function(datas) {}
          });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM