如何在HttpClient的HttpRequestMessage上设置cookie

时间:2012-09-11 16:01:29

标签: c# rest asp.net-mvc-4 asp.net-web-api

我正在尝试使用网络API HttpClient向端点发帖,要求以HTTP Cookie的形式登录,以识别帐户(这只是#ifdef' ed发布版本)。

如何将Cookie添加到HttpRequestMessage

5 个答案:

答案 0 :(得分:309)

以下是为请求设置自定义Cookie值的方法:

var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("foo", "bar"),
        new KeyValuePair<string, string>("baz", "bazinga"),
    });
    cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
    var result = client.PostAsync("/test", content).Result;
    result.EnsureSuccessStatusCode();
}

答案 1 :(得分:277)

accepted answer是在大多数情况下执行此操作的正确方法。但是,在某些情况下您需要手动设置cookie标头。通常,如果您设置“Cookie”标头,则会被忽略,但这是因为HttpClientHandler默认使用其CookieContainer属性进行Cookie。如果您将其停用,则可以将UseCookies设置为false,您可以手动设置Cookie标头,它们将显示在请求中,例如

var baseAddress = new Uri("http://example.com");
using (var handler = new HttpClientHandler { UseCookies = false })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var message = new HttpRequestMessage(HttpMethod.Get, "/test");
    message.Headers.Add("Cookie", "cookie1=value1; cookie2=value2");
    var result = await client.SendAsync(message);
    result.EnsureSuccessStatusCode();
}

答案 2 :(得分:3)

我有一个类似的问题,对于我的AspNetCore 3.1应用程序,此问题的其他答案无效。我发现在Startup.cs中配置一个命名的HttpClient并使用Cookie头的头传播非常有效。它还避免了对处理程序和客户的正确处理的所有担忧。请注意,如果不需要传播请求cookie(对不起,Op),则可以在配置客户端工厂时设置自己的cookie。

使用IServiceCollection配置服务

services.AddHttpClient("MyNamedClient").AddHeaderPropagation();
services.AddHeaderPropagation(options =>
{
    options.Headers.Add("Cookie");
});

使用IApplicationBuilder

进行配置
builder.UseHeaderPropagation();
  • IHttpClientFactory注入到控制器或中间件中。
  • 创建客户using var client = clientFactory.CreateClient("MyNamedClient");

答案 3 :(得分:1)

花了几个小时解决这个问题之后,以上答案都无济于事,所以我找到了一个非常有用的工具。

首先,我使用Telerik的Fiddler 4来详细研究我的Web请求

其次,我遇到了这个对Fiddler有用的插件:

https://github.com/sunilpottumuttu/FiddlerGenerateHttpClientCode

它只会为您生成C#代码。一个例子是:

        var uriBuilder = new UriBuilder("test.php", "test");
        var httpClient = new HttpClient();


        var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uriBuilder.ToString());



        httpRequestMessage.Headers.Add("Host", "test.com");
        httpRequestMessage.Headers.Add("Connection", "keep-alive");
     //   httpRequestMessage.Headers.Add("Content-Length", "138");
        httpRequestMessage.Headers.Add("Pragma", "no-cache");
        httpRequestMessage.Headers.Add("Cache-Control", "no-cache");
        httpRequestMessage.Headers.Add("Origin", "test.com");
        httpRequestMessage.Headers.Add("Upgrade-Insecure-Requests", "1");
    //    httpRequestMessage.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        httpRequestMessage.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
        httpRequestMessage.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        httpRequestMessage.Headers.Add("Referer", "http://www.translationdirectory.com/");
        httpRequestMessage.Headers.Add("Accept-Encoding", "gzip, deflate");
        httpRequestMessage.Headers.Add("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8");
        httpRequestMessage.Headers.Add("Cookie", "__utmc=266643403; __utmz=266643403.1537352460.3.3.utmccn=(referral)|utmcsr=google.co.uk|utmcct=/|utmcmd=referral; __utma=266643403.817561753.1532012719.1537357162.1537361568.5; __utmb=266643403; __atuvc=0%7C34%2C0%7C35%2C0%7C36%2C0%7C37%2C48%7C38; __atuvs=5ba2469fbb02458f002");


        var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;

        var httpContent = httpResponseMessage.Content;
        string result = httpResponseMessage.Content.ReadAsStringAsync().Result;

请注意,我不得不注释掉两行内容,因为此插件尚不十分完善,但仍然可以完成工作。

免责声明:无论如何,Telerik或插件的作者均未与我联系或认可。

答案 4 :(得分:1)

对我来说,简单的解决方案可以在 HttpRequestMessage 对象中设置Cookie。

protected async Task<HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken))
{
    requestMessage.Headers.Add("Cookie", $"<Cookie Name 1>=<Cookie Value 1>;<Cookie Name 2>=<Cookie Value 2>");

    return await _httpClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
}