标签: dotnet-httpclient

授权标头在重定向时丢失

下面是进行身份验证的代码,生成Authorization标头并调用API.

不幸的是,我在API上发出请求后收到401 Unauthorized错误GET.

但是,当我捕获Fiddler中的流量并重放它时,对API的调用成功,我可以看到所需的200 OK状态代码.

[Test]
public void RedirectTest()
{
    HttpResponseMessage response;
    var client = new HttpClient();
    using (var authString = new StringContent(@"{username: ""theUser"", password: ""password""}", Encoding.UTF8, "application/json"))
    {
        response = client.PostAsync("http://host/api/authenticate", authString).Result;
    }

    string result = response.Content.ReadAsStringAsync().Result;
    var authorization = JsonConvert.DeserializeObject<CustomAutorization>(result);
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authorization.Scheme, authorization.Token);
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.host+json;version=1");

    response =
        client.GetAsync("http://host/api/getSomething").Result;
    Assert.True(response.StatusCode == HttpStatusCode.OK);
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,Authorization标头丢失.

但是,在Fiddler中,标题成功传递.

知道我做错了什么吗?

.net c# rest dotnet-httpclient

20
推荐指数
2
解决办法
2万
查看次数

C#HttpClient上传速度慢

我正在尝试将大型(50 MB - 32 GB)文件上传到Google.Drive.我正在使用google-api-dotnet,它提供上传逻辑和加密支持.主要问题是上传速度慢.

我查看了api 源代码.每个文件都由块上传(我将块大小设置为4 MB)每个块都通过新的HttpRequestMessage实例上传.一旦api服务启动,就会创建HttpClient,并将其重用于所有请求.

上传速度为600千字节/秒并且稳定,而我的上行速度快10倍.

我用Wireshark捕获了流量: 慢上传-截图 每个块被分成数百或数千个小TLS包.对于每个包装好的小TLS,预计会有确认.因此产生的速度非常低.

但是当我启动Fiddler代理时,速度变得和我的上行链路一样快.TLS数据包并行传输速度非常快,稍后会收到确认: TLS-包先截图 TCP-ACK-后

我用Win7在5台PC上尝试了我的代码,并且都显示出类似的低上传速度.但是当我尝试使用Win10 PC时 - 速度非常好.我也尝试了Google.Drive客户端应用程序,它在速度方面遇到了同样的问题.我试图搜索这个行为,但我没有找到任何东西.

  1. 为什么4 MB块分为4 KB TLS数据包?我可以增加TLS包的大小吗?
  2. 如何像Fiddler那样并行发送TLS数据包?
  3. 还是有其他方法可以提高上传速度吗?

.net c# performance google-drive-api dotnet-httpclient

20
推荐指数
1
解决办法
1399
查看次数

使用.NET 4.6.2中的HttpClientFactory

我有一个.NET 4.6.2控制台应用程序(使用Simple Injector).我需要调用HTTP服务.直接使用HttpClient遇到问题,我正在尝试使用HttpClientFactory(https://github.com/aspnet/HttpClientFactory).

项目/库是.NET Standard 2.0所以它应该?? 在.NET 4.6.2中工作,但它使用像IServiceCollection这样的东西,它只在Core中.

所以我的问题是我可以在非核心应用程序中使用HttpClientFactory.

dotnet-httpclient .net-core

20
推荐指数
2
解决办法
9495
查看次数

为集成测试创建默认的 HttpClientFactory

我有一个键入的客户端,我想将其注册为单例:

public class SomeHttpClient
{
    private readonly IHttpClientFactory _clientFactory;

    public SomeHttpClient(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }

    public Task MakeSomeCallAsync(...)
    {
        var client = _clientFactory.Create();
        // Do more stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

类型化的客户端必须是单例的,因为它有一些断路器逻辑,如果 API 对客户端进行速率限制,则会中断电路。电路必须在整个应用程序中断开,显然不仅仅是当前的请求管道(否则客户端将继续访问已经从其他实例进行速率限制的 API)。这已经通过使用封装了该功能的类型化客户端(虽然不是 Polly)来实现的。

现在因为类型化的客户端将是一个单身人士,我们不能注入一个单身人士,HttpClient因为这会带来我们以前在一个 long living 中遇到的所有问题HttpClient。显而易见的解决方案是注入一个HttpClientFactory现在可以用来在HttpClient每次键入的客户端需要一个实例时发出一个实例而不必担心生命周期管理等,因为这已经推迟到HttpClientFactory现在。

我现在的问题是如何HttpClientFactory为一个简单的功能集成测试创建默认值,我想在其中实例化一个类型化的客户端,看看我是否可以点击 API 并从自动化测试中获得成功的响应?

我不想设置一个 ASP.NET Core TestServer 和一个围绕它的整个应用程序,因为这对于我现在想要做的那种功能测试来说太过分了。

没有可用于注入HttpClientFactory?

c# dotnet-httpclient .net-core asp.net-core httpclientfactory

20
推荐指数
3
解决办法
6340
查看次数

类型化 HttpClient 与 IHttpClientFactory

以下两种设置 HttpClient 的场景有什么区别吗?

我应该选择其中一种而不是另一种吗?

键入的客户端:

public class CatalogService 
{
    private readonly HttpClient _httpClient;
    
    public CatalogService(HttpClient httpClient) {
        _httpClient = httpClient;
    }
    
    public async Task<string> Get() {
        var response = await _httpClient.GetAsync();
        ....
    }
    
    public async Task Post() {
        var response = await _httpClient.PostAsync();
        ...
    }
}
// Startup.cs
//Add http client services at ConfigureServices(IServiceCollection services)
services.AddHttpClient<ICatalogService, CatalogService>();
Run Code Online (Sandbox Code Playgroud)

IHttpClientFactory:

public class CatalogService 
{
    private readonly IHttpClientFactory _factory;
    
    public CatalogService(IHttpClientFactory factory) {
        _factory = factory;
    }
    
    public async Task<string> Get() {
        var …
Run Code Online (Sandbox Code Playgroud)

c# async-await dotnet-httpclient asp.net-core httpclientfactory

20
推荐指数
3
解决办法
1万
查看次数

使用FormCollection中的数据创建异步HttpClient发布请求

我正在做一个Asp.Net MVC 4项目,我正在寻找我们的api服务的内部请求(如代理).

这就是我的控制器中索引方法的样子.我被困在PostAsync部分.

[HttpPost]
public async Task<ActionResult> Index(FormCollection body){

   HttpClient httpClient  = new HttpClient();
   httpClient.BaseAddress = new Uri("http://myapi.com");

   // posts to http://myapi.com/users
   var response = await httpClient.PostAsync("users", body);

   if(response.isSuccessStatusCode) return Json(new {
        status = true,
        url    = response.Content.Url
   });
}
Run Code Online (Sandbox Code Playgroud)

我想将我的"application/x-form-urlencoded""body"内容传递给PostAsync POST方法.但是,我得到一个错误,读取"body不是HttpContent类型".

我不能演员或转换.现在怎么办?

让我知道我在这里做错了什么.

埃里克

c# formcollection asp.net-mvc-4 dotnet-httpclient

19
推荐指数
1
解决办法
2万
查看次数

如何在HttpReponseMessage上设置响应cookie?

我想在web api中创建一个演示登录服务,需要在响应上设置一个cookie.我怎么做?或者有更好的授权方式吗?

asp.net-web-api dotnet-httpclient

18
推荐指数
2
解决办法
3万
查看次数

HttpResponseMessage.Content.Headers ContentDisposition为null

使用HttpClient下载文件时,我首先下载标题然后下载内容.下载头文件时,我可以在HttpResponseMessage的Content属性上看到Headers集合,但是当通过Headers上的ContentDisposition访问它时,得到null 截图

为什么会这样?提琴手显示标题很好......

码:

var responseMessage = await httpClient.GetAsync(uri, 
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(continueOnCapturedContext: false);
Run Code Online (Sandbox Code Playgroud)

更新1

看起来这个类遵循RFC 2616中概述的Content-Disposition实现,并且无法处理Content-Disposition实现更新RFC 6266.RFC 2616将filename参数值定义为带引号的字符串,其中更新RFC 6266仅表明它应该是.

RFC 2616语法

content-disposition = "Content-Disposition" ":"
                          disposition-type *( ";" disposition-parm )
    disposition-type = "attachment" | disp-extension-token
    disposition-parm = filename-parm | disp-extension-parm
    filename-parm = "filename" "=" quoted-string
    disp-extension-token = token
    disp-extension-parm = token "=" ( token | quoted-string )
Run Code Online (Sandbox Code Playgroud)

RFC 6266语法

content-disposition = "Content-Disposition" ":"
                        disposition-type *( ";" disposition-parm )

 disposition-type    = "inline" | "attachment" …
Run Code Online (Sandbox Code Playgroud)

c# dotnet-httpclient

18
推荐指数
2
解决办法
8107
查看次数

如何从HttpResponseMessage读取cookie?

这是我最近的代码:

HttpClient authClient = new HttpClient();
authClient.BaseAddress = new Uri("http://localhost:4999/test_db/_session");
authClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var user = new LoginUserSecretModel
{
    name = userKey,
    password = loginData.Password,
};
HttpResponseMessage authenticationResponse = authClient.PostAsJsonAsync("", user).Result;
Run Code Online (Sandbox Code Playgroud)

c# cookies asp.net-web-api dotnet-httpclient

18
推荐指数
4
解决办法
2万
查看次数

HttpClient可以为GET请求发送内容或正文吗?

目前要向API接口发送参数化GET请求,我正在编写以下代码:

api/master/city/filter?cityid=1&citycode='ny'
Run Code Online (Sandbox Code Playgroud)

但我发现URL长度限制为2,083个字符.

为了避免这种情况,我想在内容体中以json格式发送参数以获取GET请求.

但是,我发现HttpClient的Get方法都不允许发送内容正文.对于POST,我可以看到HttpClient中有一个名为PostAsync的方法允许内容体.

有没有办法为不在URL中的GET请求发送参数以避免URL长度限制?

c# get request dotnet-httpclient

18
推荐指数
2
解决办法
2万
查看次数