标签: httpclientfactory

使用 IHttpClientFactory 设置每个请求的请求标头

我正在使用类型化客户端IHttpClientFactory。像这样:

// Startup.cs
services.AddHttpClient<MyHttpClient>()

// MyHttpClient.cs
public class MyHttpClient
{
    public MyHttpClient(HttpClient client)
    {
        Client = client;
    }

    public HttpClient Client { get; }
}

// MyService.cs
public class MyService {
    public MyService(MyHttpClient httpClient) {}

    public async Task SendRequestAsync(string uri, string accessToken) {
        _httpClient.Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        await _httpClient.Client.GetAsync(uri);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是如何运作的。请求标头是仅针对此请求设置,还是针对使用 . 的此实例发出的每个后续请求设置httpClient。如何为每个请求设置标头?

c# asp.net-core asp.net-core-2.1 httpclientfactory

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

DelegateHandler 的 DI 无法正常工作

刚开始使用 HttpFactory,并且非常困惑它的 DI 是如何工作的,例如这条线的工作方式

services.AddHttpClient<IMyClient, MyClient>()
   .AddHttpMessageHandler(s => new UserAgentDelegatingHandler());
Run Code Online (Sandbox Code Playgroud)

这不

services.AddHttpClient<IMyClient, MyClient>()
  .AddHttpMessageHandler<UserAgentDelegatingHandler>();
Run Code Online (Sandbox Code Playgroud)

返回

“消息:System.InvalidOperationException:没有注册‘UserAgentDelegatingHandler’类型的服务。”

这里的情况相同,以下代码工作正常

services.AddHttpContextAccessor();
services.AddHttpClient<IMyClient, MyClient>()
   .AddHttpMessageHandler(s => new CookieDelegateHandler(s.GetRequiredService<IHttpContextAccessor>()));
Run Code Online (Sandbox Code Playgroud)

但这并没有

services.AddHttpContextAccessor();
services.AddHttpClient<IMyClient, MyClient>()
   .AddHttpMessageHandler<CookieDelegateHandler>();
Run Code Online (Sandbox Code Playgroud)

我从这些示例中阅读了很多 HttpClientFactory 用法示例,以及我的 DelegateHandlers。

我做错了什么?

c# asp.net-core httpclientfactory

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

使用 IHttpClientFactory 使用外部 API 时存储访问和刷新令牌的位置。网络核心

我使用 IHttpClientFactory 发送请求并接收从我的 Web API 到使用 Net Core 2.2 的外部 API 的 HTTP 响应。

用于向 API 发送请求的访问令牌和刷新令牌已存储在 appsettings.json 中。当请求返回 403 或 401 错误时,我会动态获取一个新令牌并将其添加到请求的标头中。

但是如何使用新的访问和刷新令牌更新 appsettings.json 以便将其用于后续请求。

是否有比 appsettings.json 更好的方法来存储访问和刷新令牌?

token asp.net-core refresh-token httpclientfactory

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

控制台应用程序后台服务中 httpclientfactory 的 DI

我有一个带有简单消费后台服务的控制台程序,它需要从使用 HttpClientFactory 的作用域服务调用函数来调用外部 API 并将结果返回给消费后台服务。

在网上查看了几个示例后,我想要非常简单,以消除代码中所有可能的复杂性。

public class Program
    {
        public static async Task Main(string[] args)
        {
            var host = new HostBuilder()
                .ConfigureLogging((hostContext, config) =>
                {
                    config.AddConsole();
                })
                .ConfigureAppConfiguration((hostContext, config) =>
                {
                    config.AddJsonFile("appsettings.json", optional: true);
                    config.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
                    config.AddCommandLine(args);
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<ConsumeMessageService>();
                    services.AddScoped<IScopedArcGisServices, ScopedArcGisServices>();
                })
        .UseConsoleLifetime()
        .Build();

        using (host)
        {
            // Start the host
            await host.StartAsync();

            // Wait for the host to shutdown
            await host.WaitForShutdownAsync();
        }
        }
    }
Run Code Online (Sandbox Code Playgroud)
public class ConsumeMessageService : IHostedService
    {
        private …
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection httpclientfactory asp.net-core-hosted-services

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

如何在 Blazor WebAssemly 应用程序中引用 IHttpClientFactory?

在 VS 2019 中,我尝试HttpClient在 Blazor WebAssemply 应用程序中测试使用。创建新项目时,我选择了该.Net Core 3.1选项。在Program.cs中,HttpClient服务注册如下:

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
Run Code Online (Sandbox Code Playgroud)

在“框架”部分下,system.net.http列出了。

@inject IHttpClientFactory http我们遇到了无法添加新 Razor 组件的问题。错误消息是:

错误 CS0246 找不到类型或命名空间名称“IHttpClientFactory”(您是否缺少 using 指令或程序集引用?)

Microsoft 站点的在线文档显示了IHttpClientFactorySystem.Net.Http包中定义的。我遇到的错误的根本原因是什么以及如何修复它?

c# blazor httpclientfactory blazor-webassembly

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

在 .NET Core 中进行 HTTP 调用而无需依赖注入

我需要进行一系列 HTTP 调用以从第 3 方保管库获取数据库凭据,因为我需要运行此代码Program.cs,或者最晚Startup.cs在添加 DBContext 之前,我需要能够在不使用 DBContext 的情况下进行这些调用使用IHttpClientFactory,因为这需要依赖注入已经初始化。

以下代码在运行时调用时工作正常,但在步骤期间不起作用ConfigureAppConfiguration

HttpClient client = _clientFactory.CreateClient();

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, $"{_configuration["CredentialsVault:vaultUrl"]}Auth/SignAppIn");
request.Headers.Add("Authorization", $"PS-Auth key={_apiKey}; runas={_runAsUser};");

var response = await client.SendAsync(request);
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以在不依赖依赖注入的情况下进行 HTTP 调用,或者延迟AddDbContext到依赖注入设置之后?

我尝试创建一个 HttpClient 实例,如下所示:

HttpClient client = new HttpClient();
Run Code Online (Sandbox Code Playgroud)

然而,这似乎不起作用,根据这个问题,它不应该像这样实例化。

c# dotnet-httpclient .net-core httpclientfactory

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

如何限制.net Core API项目中多个线程上对HttpClient的所有传出异步调用

我正在设计一个.net核心Web API,它使用了我无法控制的外部API。我在堆栈溢出中找到了一些极好的答案,这些问题使我可以在使用semaphoreslim的同一线程中限制对此外部API的请求。我想知道如何最好地将这种限制扩展到整个应用程序,而不仅仅是限制特定任务列表。我一直在学习HttpMessageHandlers,这似乎是拦截所有传出消息并应用限制的一种可能方法。但是我担心线程安全性和锁定问题,我可能不了解。我包括了当前的限制代码,希望对理解我正在尝试做的事情有所帮助,但是要跨越多个线程,并且不断添加任务而不是预先定义的任务列表。

private static async Task<List<iMISPagedResultResponse>> GetAsyncThrottled(List<int> pages, int throttle, IiMISClient client, string url, int limit)
{
        var rtn = new List<PagedResultResponse>();
        var allTasks = new List<Task>();
        var throttler = new SemaphoreSlim(initialCount: throttle);
        foreach (var page in pages)
        {
            await throttler.WaitAsync();
            allTasks.Add(
                Task.Run(async () =>
                {
                    try
                    {
                        var result = await GetPagedResult(client, url, page);
                        return result;
                    }
                    finally
                    {
                        throttler.Release();
                    }
                }));
        }
        await Task.WhenAll(allTasks);
        foreach (var task in allTasks)
        {
            var result = ((Task<PagedResultResponse>)task).Result;
            rtn.Add(result);
        }
        return rtn; …
Run Code Online (Sandbox Code Playgroud)

semaphore dotnet-httpclient asp.net-core httpclientfactory

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

Azure 服务总线的 ServiceBusClient - 重用 tcp 连接,就像 HttpClientFactory 一样

我有许多 CRUD API,它们通过 HTTP 调用 (.NET 5) 相互通信。
为了避免打开太多的 tcp 连接,我在所有这些服务中通过 DI使用HttpClientFactory 。这效果很好,我没有遇到太多通过 HTTP 打开的连接。

但我的 Azure 应用服务仍然抱怨 SNAT 连接过多:

在此输入图像描述

我猜原因是Azure服务总线。我的 API 的每次调用都会将事件写入总线。
为此,我在每次调用时创建一个新实例:

            await using (ServiceBusClient client = new ServiceBusClient(_serviceBusConnectionString))
                {
                    var messageObject = new { message.Name, message.Body };
                    var messageJson = JsonConvert.SerializeObject(messageObject);
                    ServiceBusSender sender = client.CreateSender(_topicName);
                    await sender.SendMessageAsync(new ServiceBusMessage(messageJson));
                }
Run Code Online (Sandbox Code Playgroud)

许多开发人员都像这样使用 HttpClient(这是一个坏主意,请阅读上面的文章中的原因)。HttpClient 的解决方案是 .NET 为此目的提供的 AddHttpClient 方法。

但是 Azure 服务总线呢?没有什么像 AzureServiceBusFactory 之类的东西,将 AzureServiceBus 添加为单例并不是一个好主意,因为每次调用的配置都应该不同。

如何确保连接池也重新用于 Azure 服务总线连接?我错过了什么最佳实践吗?或者您认为连接问题还有其他原因吗?

编辑:

接受的答案是正确的。这工作正常,我的错误消失了。只需使用以下命令添加服务总线客户端:

            services.AddAzureClients(cfg =>
            {
                cfg.AddServiceBusClient("your-connection-string");
            });
Run Code Online (Sandbox Code Playgroud)

之后,您就可以在您的所有服务中轻松通过 DI …

c# azureservicebus httpclientfactory .net-5

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