【问题标题】:ASP.NET Core 2 get cookies from HttpResponseMessageASP.NET Core 2 从 HttpResponseMessage 获取 cookie
【发布时间】:2019-02-21 13:08:13
【问题描述】:

目前我正在开发一个使用 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 和一些验证令牌?

对不起,如果我做错了什么,这是我的第一篇文章。

编辑

通过在请求管道中添加一个 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 标头中获取所有 cookie,并将其添加到请求的 Cookie 标头中。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 是否有任何构造函数被命中(如果你在那里设置断点?
    • 您的方法对我不起作用,因为 MyClient 不是 HttpClient 的自定义实现,而是来自 ASP.NET Core 2 Framework 附带的 HttpClientFactory 的类型化 HttpClient 实例。我使用以下方式来实现它:link这就是为什么你的方法对我不起作用,但我非常感谢你的努力。
    【解决方案2】:

    您编辑的答案尚不清楚,因此我在此处进行了总结。 此外,无需显式设置HttpClientHandler.UseCookies = true 或拥有CookieContainer

    要从调用中获取 cookie,您可以简单地读取 "Set-Cookie" 响应标头:

    HttpResponseMessage response = await httpClient.GetAsync(uri);
    IEnumerable<string> cookies = response.Headers.SingleOrDefault(header => header.Key == "Set-Cookie")?.Value;
    

    【讨论】:

      【解决方案3】:
      $.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) {}
                });
      

      【讨论】:

      • 您好,这个问题是我自己回答的。您的答案没有提供有效的解决方案,因为您编写的是 JavaScript,并且问题要求使用 C# 编写的 asp.net 核心
      猜你喜欢
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 2017-08-09
      • 2020-12-13
      • 2017-02-25
      • 2020-11-16
      相关资源
      最近更新 更多