IHttpClientFactory新的ASP.NET Core 2.1中有一个非常酷的功能,
https://www.hanselman.com/blog/HttpClientFactoryForTypedHttpClientInstancesInASPNETCore21.aspx
我正在尝试在ASP.NET Core 2.1 Preview-2应用程序中使用此功能,但是我需要HttpClient在.NET Standard 2.0中的类库中使用。
有一次,我执行AddHttpClient中ConfigureServices()的Startup.cs,我怎么通过这个HttpClientFactory或命名具体HttpClient到我在.NET 2.0标准类库创建的API客户端?该客户端几乎可以处理我对第三方的所有API调用。
基本上,我只是想将特定的名称添加HttpClient到我的中thirdPartyApiClient。
这是我的代码ConfigureServices():
public void ConfigureServices(IServiceCollection services)
{
// Create HttpClient's
services.AddHttpClient("Api123Client", client =>
{
client.BaseAddress = new Uri("https://api123.com/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
services.AddHttpClient("Api4567Client", client =>
{
client.BaseAddress = new Uri("https://api4567.com/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
}
Run Code Online (Sandbox Code Playgroud) 我需要在HttpClientFactory中添加证书.老实现HttpClient看看这个:
var cookieContainer = new CookieContainer();
var handler = new HttpClientHandler { CookieContainer = cookieContainer };
var basePath = Directory.GetCurrentDirectory();
var certificatePath = Path.Combine(basePath, certPath);
var fileExists = File.Exists(certificatePath);
if (!fileExists)
throw new ArgumentException(certificatePath);
var certificate = new X509Certificate2(certificatePath, certPwd);
handler.ClientCertificates.Add(certificate);
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept));
client.DefaultRequestHeaders.Add("ApiKey", apiKey);
var body = new { UserName = username, UserPassword = password };
var jsonBody = JsonConvert.SerializeObject(body);
var content = new StringContent(jsonBody, Encoding.UTF8, contentType);
var …Run Code Online (Sandbox Code Playgroud) 我应该如何使用 HttpClientFactory 返回 HttpClient 的实例,其 uri 和凭据是在调用时确定的?
现有代码如下所示:
var httpClientHandler = new HttpClientHandler()
{
Credentials = new NetworkCredential(userName, password),
};
HttpClient client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri(_appSetting.ServiceURI);
Run Code Online (Sandbox Code Playgroud) 我正在使用IHttpClientFactory发送请求和使用Net Core 2.2从两个外部API接收HTTP响应。
我正在寻找一种很好的策略,以使用存储在appsettings.json中的刷新令牌来获取新的访问令牌。当当前请求返回403或401错误时,需要请求新的访问令牌。获得新的访问和刷新令牌后,需要用新值更新appsettings.json以便在后续请求中使用。
我正在使用两个客户端将请求发送到两个不同的API,但是只有其中一个使用令牌身份验证机制。
我已经实现了一些简单的方法,但是我正在寻找一种更优雅的解决方案,该解决方案可以在当前令牌到期时动态更新标头:
我已经在Startup.ConfigureServices方法中注册了IHttpClientFactory,如下所示:
services.AddHttpClient();
Run Code Online (Sandbox Code Playgroud)
注册后,我将以两种不同的方法使用它来调用两种不同的API,第一种方法是:
public async Task<AirCallRequest> GetInformationAsync(AirCallModel model)
{
try
{
CandidateResults modelCandidateResult = null;
var request = new HttpRequestMessage(HttpMethod.Get,
"https://*******/v2/*****");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _appSettings.Value.Token);
var clientJAAPI = _httpClientFactory.CreateClient();
var responseclientJAAPI = await clientJAAPI.SendAsync(request);
if (responseclientJAAPI.IsSuccessStatusCode)
{
modelCandidateResult = await responseclientJAAPI.Content
.ReadAsAsync<CandidateResults>();
....
}
if ((responseclientJAAPI .StatusCode.ToString() == "Unauthorized")
{
await RefreshAccessToken();
//Calls recursively this method again
return await GetInformationAsync(model);
}
return null;
}
catch (Exception e)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
刷新令牌方法如下所示: …
在 ConfigureServices 方法中一次添加 httpContextAccessor 与为每个 HttpClient 配置添加 HttpContextAccessor 之间有什么区别。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// FIRST VERSION
services.AddHttpContextAccessor();
// SECOND VERSION
var myService1 = services.AddHttpClient<TestHttpClient1>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient1"]);
});
myService1.Services.AddHttpContextAccessor();
var myService2 = services.AddHttpClient<TestHttpClient2>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient2"]);
});
myService2.Services.AddHttpContextAccessor();
}
Run Code Online (Sandbox Code Playgroud)
我的猜测是认为在第二个版本中,我们有两个单例,一个用于类 TestHttpClient1,另一个用于 TestHttpClient2 但我不明白为什么要这样做,因为我在生产中看到了这段代码。
正如标题所暗示的,我有一些代码可以调用IHttpClientFactory.CreateClient()来创建一个 HttpClient 实例。
我在 .Net Core 3.1 中这样做
我需要嘲笑这个。根据这个问题“C# Mock IHttpclient & CreateClient”,以下应该有效......
[Test]
public void Mytest() {
var httpClientFactory = new Mock<IHttpClientFactory>(MockBehavior.Strict);
httpMessageHandler = new Mock<HttpMessageHandler>(MockBehavior.Strict);
httpMessageHandler.Protected()
// Setup the PROTECTED method to mock
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.BadRequest,
})
.Verifiable();
var httpClient = new HttpClient(httpMessageHandler.Object);
httpClientFactory.Setup(_ => _.CreateClient()) // This fails
.Returns(httpClient).Verifiable();
systemUnderTest = new MyService(httpClientFactory.Object);
var result …Run Code Online (Sandbox Code Playgroud) 使用 C#、.NET Core 3.1
我httpclient通过 in添加一个单例startup.cs:
services.AddHttpClient<IClientLogic, ClientLogicA>().ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
var cert= GetCertFromX();
handler.ClientCertificates.Add(cert);
return handler;
});
Run Code Online (Sandbox Code Playgroud)
但是,假设稍后在ClientLogicA课堂上,我想更改证书,我该如何执行此操作,并且更改是否会持续存在以供将来使用 httpclient 单例?
c# dependency-injection dotnet-httpclient asp.net-core httpclientfactory
我在工厂中注册我的 HttpClient:
services.AddHttpClient<ICatalogService, CatalogService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(2));
Run Code Online (Sandbox Code Playgroud)
此 ICatalogService 通过构造函数注入到单例服务中。
2 分钟后我会在内部收到一个新的 HttpMessageHandler 还是仅在 2 分钟后将 ICatalogService 注入到非单例服务中?
基本上,当包装 HttpHandler 用作单例时,内部 HttpMessageHandler 也会过期吗?
dependency-injection httpclient asp.net-core httpclientfactory
我的服务定义:
var host = new HostBuilder().ConfigureServices(services =>
{
services
.AddHttpClient<Downloader>()
.AddPolicyHandler((services, request) =>
HttpPolicyExtensions
.HandleTransientHttpError()
.Or<SocketException>()
.Or<HttpRequestException>()
.WaitAndRetryAsync(
new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10) },
onRetry: (outcome, timespan, retryAttempt, context) =>
{
Console.WriteLine($"Delaying {timespan}, retrying {retryAttempt}.");
}));
services.AddTransient<Downloader>();
}).Build();
Run Code Online (Sandbox Code Playgroud)
实施Downloader:
class Downloader
{
private HttpClient _client;
public Downloader(IHttpClientFactory factory)
{
_client = factory.CreateClient();
}
public Download()
{
await _client.GetAsync(new Uri("localhost:8800")); // A port that no application is listening
}
}
Run Code Online (Sandbox Code Playgroud)
通过此设置,我预计会看到三次尝试查询端点,并将日志消息打印到控制台(我也尝试使用记录器但未成功,为简单起见,这里使用控制台)。
我看到的是未处理的异常消息(我只希望在重试和打印日志后看到),而不是调试消息。
未处理的异常:System.Net.Http.HttpRequestException:无法建立连接,因为目标计算机主动拒绝它。(127.0.0.1:8800) ---> System.Net.Sockets.SocketException (10061): 无法建立连接,因为目标计算机主动拒绝连接。
c# dependency-injection dotnet-httpclient polly httpclientfactory
我有许多服务需要使用来自 HttpClientFactory 的类型化 HttpClient。虽然我可以解析一项服务,但我无法解析该服务的 IEnumerable。
interface IMyHttpClient
{
}
class MyHttpClient: IMyHttpClient
{
public MyHttpClient(HttpClient client)
{
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient()
.AddHttpClient<IMyHttpClient, MyHttpClient>();
var builder = new ContainerBuilder();
// Exception goes away when remove this line
builder.RegisterType<MyHttpClient>().As<IMyHttpClient>();
builder.Populate(services);
var provider = builder.Build();
// ============== This works
// provider.Resolve<IMyHttpClient>();
// ============== This throws exception
provider.Resolve<IEnumerable<IMyHttpClient>>();
}
}
Run Code Online (Sandbox Code Playgroud)
构造函数将被调用一次,然后抛出异常:
``` DependencyResolutionException:在类型“ConsoleApp2.MyHttpClient”上找不到任何带有“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”的构造函数可以使用可用的服务和参数调用:无法解析参数“System.Net.Http.HttpClient”构造函数 'Void .ctor(System.Net.Http.HttpClient)' 的客户端'。
``
问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我只想使用 …
c# ×7
asp.net-core ×5
.net-core ×2
appsettings ×1
autofac ×1
httpclient ×1
polly ×1
unit-testing ×1