ChrisBellew
ChrisBellew

Reputation: 1174

Does .NET Core HttpClient have the concept of interceptors?

I would like to wrap some timing logic around all calls made through HttpClient from my ASP.NET Core app, including calls made from 3rd party libraries.

Does HttpClient in .NET Core have something I can plug into to run some code on every request?

Upvotes: 17

Views: 15607

Answers (1)

Ilya Chumakov
Ilya Chumakov

Reputation: 25019

Yes, it does. HttpClient produces a HTTP request via DelegatingHandler chain. To intercept the HttpClient request, you can add a derived handler with overrided SendAsync method to that chain.

Usage:

var handler = new ExampleHttpHandler(fooService);

var client = new HttpClient(handler);

var response = await client.GetAsync("http://google.com");

Implementation:

public class ExampleHttpHandler : DelegatingHandler
{
    //use this constructor if a handler is registered in DI to inject dependencies
    public ExampleHttpHandler(FooService service) : this(service, null)
    {
    }

    //Use this constructor if a handler is created manually.
    //Otherwise, use DelegatingHandler.InnerHandler public property to set the next handler.
    public ExampleHttpHandler(FooService service, HttpMessageHandler innerHandler)
    {
        //the last (inner) handler in the pipeline should be the "real" one.
        //To make a HTTP request, create a HttpClientHandler instance.
        InnerHandler = innerHandler ?? new HttpClientHandler();
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        //add any logic here
        return await base.SendAsync(request, cancellationToken);
    }
}

BTW, I recommend moving as much business logic out of a custom handler as possible to simplify unit-testing it. Also, check HttpClient lifetime guidelines for best practices in .NET http client creation.

Upvotes: 14

Related Questions