Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 200
ChrisBellew Avatar asked Feb 09 '17 07:02

ChrisBellew


People also ask

What is .NET interceptor?

An interceptor is a class that implements IInterceptor interface (of Castle Windsor). It defines the Intercept method which gets an IInvocation argument. With this invocation argument, we can investigate the executing method, method arguments, return value, method's declared class, assembly and much more.

What are interceptors in C#?

What are Interceptors? Interceptors check each and every incoming and outgoing request to the server and are also able to manipulate them before actually sending to the server.

What is HttpClient in asp net core?

Using HttpClient to Send HTTP PATCH Requests in ASP.NET Core. In this article, we learn how to use HttpClient to send HTTP PATCH requests to achieve partial updates of our resources, thus improving the application's performance. Using Streams with HttpClient to Improve Performance and Memory Usage.

Is HttpClient scoped?

The HttpClient instances injected by DI, can be disposed of safely, because the associated HttpMessageHandler is managed by the factory. As a matter of fact, injected HttpClient instances are Scoped from a DI perspective.


1 Answers

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(new ExampleHttpHandler(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 a "real" handler.
        //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.

like image 92
Ilya Chumakov Avatar answered Sep 20 '22 15:09

Ilya Chumakov