Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 840
SirOneOfMany Avatar asked Sep 17 '18 14:09

SirOneOfMany


People also ask

How do I access cookies in asp net?

Cookies is a small piece of information stored on the client machine. This file is located on client machines "C:\Document and Settings\Currently_Login user\Cookie" path. Its is used to store user preference information like Username, Password,City and PhoneNo etc on client machines.

What is Aspnet cookies cookie?

ASP.NET Cookie is a small bit of text that is used to store user-specific information. This information can be read by the web application whenever user visits the site. When a user requests for a web page, web server sends not just a page, but also a cookie containing the date and time.

How do I return a response in .NET core API?

IActionResult Return Type in ASP.NET Core Web API: The IActionResult is an interface and it is used to return multiple types of data. For example, if you want to return NotFound, OK, Redirect, etc. data from your action method then you need to use IActionResult as the return type from your action method.


2 Answers

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; }
like image 198
Martin Zikmund Avatar answered Oct 18 '22 22:10

Martin Zikmund


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;
like image 42
Daniel Avatar answered Oct 18 '22 22:10

Daniel