【发布时间】:2021-07-19 07:22:30
【问题描述】:
我已经实现了一个简单的自定义消息处理程序来记录通话时间。
我的创业课
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient(nameof(HttpClient))
.AddHttpMessageHandler<AppmetricsExternalCallMessageHandler>();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "HttpClient", Version = "v1" });
});
}
自定义处理程序
public class AppmetricsExternalCallMessageHandler : DelegatingHandler
{
private readonly ILogger<AppmetricsExternalCallMessageHandler> _logger;
public AppmetricsExternalCallMessageHandler(ILogger<AppmetricsExternalCallMessageHandler> logger)
{
_logger = logger;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Stopwatch sw = Stopwatch.StartNew();
try
{
var res = await base.SendAsync(request, cancellationToken);
_logger.LogInformation(sw.ElapsedMilliseconds.ToString(), request.RequestUri.LocalPath);
return res;
}
catch (Exception)
{
_logger.LogInformation(sw.ElapsedMilliseconds.ToString(), request.RequestUri.LocalPath);
throw;
}
}
}
现在我创建了一个使用HttpClientFactory调用虚拟api的端点
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly IHttpClientFactory _clientFactory;
public WeatherForecastController(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
[HttpGet, Route("test")]
public async Task<ActionResult> Test()
{
var request = new HttpRequestMessage(HttpMethod.Get,
"https://jsonplaceholder.typicode.com/posts");
var client = _clientFactory.CreateClient(nameof(HttpClient));
//var response = await client.SendAsync(request);
var response = await client.GetAsync("https://jsonplaceholder.typicode.com/posts");
if (response.IsSuccessStatusCode)
return Ok();
return BadRequest();
}
...
}
当我调用端点时出现错误
“HttpClient.AppmetricsExternalCallMessageHandler”类型没有服务 已注册。在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.c__4`1.b__4_1(HttpMessageHandlerBuilder b) 在 Microsoft.Extensions.Http.DefaultHttpClientFactory.c__DisplayClass17_0.g__Configure|0(HttpMessageHandlerBuilder b) 在 Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.c__DisplayClass3_0.b__0(HttpMessageHandlerBuilder 建设者)在 Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(字符串 名称)在 Microsoft.Extensions.Http.DefaultHttpClientFactory.c__DisplayClass14_0.<.ctor>b__1()
我做错了什么?
【问题讨论】:
-
您没有使用您配置的客户端 (
.AddHttpClient(nameof(HttpClient)))。创建客户端时指定名称_clientFactory.CreateClient(nameof(HttpClient))。 -
@abdusco 是的,你是对的,更新帖子,因为我得到另一个错误
-
添加
services.AddScoped<AppmetricsExternalCallMessageHandler>() -
@abdusco 再次非常感谢您,将处理程序注册为单例是一种好方法吗?
-
不,ASP.NET Core 缓存/池化处理程序本身。让它为您控制处理程序的生命周期。坚持使用 Transient & Scoped 除非你知道你需要一个单例(通常是为了缓存一个全局状态)。同时添加
using var sw = Stopwatch.StartNew()。你需要处理定时器。
标签: c# asp.net-core .net-core dotnet-httpclient .net-5