c# - ASP.NET Core 2 从 HttpResponseMessage 获取 cookie

标签 c# cookies dotnet-httpclient asp.net-core-2.1 httpclientfactory

目前我正在开发一个用 ASP.NET Core 2 编写的项目,我正在尝试从第三方网站获取 JSON 文件。问题是该网站需要一些 cookie 才能从中检索数据。我在我的 Startup.cs 文件中实现了一个类型化的 HttpClient,如下所示:

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

有什么方法可以访问 CookieContainer 以使用 CookieContainer.GetCookies() 方法,以便我可以从 HttpResponseMessage 复制各种 cookie,例如 Session Cookie 和一些验证 token ?

抱歉,如果我做错了什么,这是我的第一篇文章。

编辑

通过在请求管道中添加 HttpMessageHandler 使其工作

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

并编辑HttpMessageHandler中的http头信息

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

    }

}

此方法从 Set-Cookie header 中获取所有 cookie,并将其添加到请求的 Cookie header 中。

最佳答案

如果 MyClientHttpClient 的自定义实现,您可以重载构造函数以存储对 HttpClientHandler 的引用:

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

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

public HttpMessageHandler Handler { get; }

关于c# - ASP.NET Core 2 从 HttpResponseMessage 获取 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52370605/

相关文章:

c# - 捕获内部密封异常

c# - 区分HttpClient请求失败类型

c# - 实体数据栏和数据栏最小值的手动版本和编码版本之间的外观不一致

c# - 列出要在 View 中显示的数据库文件的内容

c# - 我如何选择退出 JSON 契约(Contract)解析器

java - 服务器发送带有附加 Cookie 的事件客户端

c# - 如何为 C# 生成输出为 Azure DevOps Wiki 的 Markdown 的文档?

http - Servicestack 请求 header 不包含 cookie

ruby - 如何在 ruby​​ net/http 中实现 cookie 支持?

c# - 服务突然抛出 SocketException,没有明显变化