Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement a custom message handler to log the response time HttpClient .net 5

I have implemented a simple custom message handler to log the time that takes a call.

My startup class

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" });
    });
}

The custom handler

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;
        }
    }
}

and now i have created an end point which call a dummy api using HttpClientFactory

[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();
    }
    ...
}

when i call the endpoint i get an error

No service for type 'HttpClient.AppmetricsExternalCallMessageHandler' has been registered. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__4`1.b__4_1(HttpMessageHandlerBuilder b) at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass17_0.g__Configure|0(HttpMessageHandlerBuilder b) at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass3_0.b__0(HttpMessageHandlerBuilder builder) at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name) at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__1()

What i am doing wrong?

like image 782
dimmits Avatar asked Feb 06 '26 17:02

dimmits


1 Answers

You can try this, work with dotnet 6.0 No need to add a httpclient

services.AddHttpClient();
        services.ConfigureAll<HttpClientFactoryOptions>(options =>
        {
            options.HttpMessageHandlerBuilderActions.Add(b => b.AdditionalHandlers.Add(new CustomMessageHandler()));
        });
like image 159
jeremylb Avatar answered Feb 08 '26 06:02

jeremylb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!