Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding handler to default http client in ASP.NET Core [duplicate]

Is there a way to add handlers to the default HTTP client in ASP.NET Core? Something like this?

.AddHttpClient()
.AddHttpMessageHandler<Handler1>()
.AddHttpMessageHandler<Handler2>();
like image 517
Shags Avatar asked Aug 01 '18 21:08

Shags


People also ask

Can you reuse HttpClient C#?

When you use the same instance of HttpClient for multiple requests (sequential and concurrent) to the same URL, it'll reuse connections. Requests that get to reuse a connection are 5.5-8.5x faster than requests that have to open a new connection.

Can HttpClient be Singleton?

Another issue that developers run into is when using a shared instance of HttpClient in long-running processes. In a situation where the HttpClient is instantiated as a singleton or a static object, it fails to handle the DNS changes as described in this issue of the dotnet/runtime GitHub repository.

What is HttpClient handler?

The default handler is HttpClientHandler, which sends the request over the network and gets the response from the server. You can insert custom message handlers into the client pipeline: ASP.NET Web API also uses message handlers on the server side. For more information, see HTTP Message Handlers.

What is HTTP handler in ASP.NET Core?

In an ASP.NET web application, the HTTP handler is a process that is executed on each response to the requests made to the web server. We can create our own custom HTTP handlers to render desired output. Handler class for redirection. The following is the code to redirect all the . aspx extension pages to a new page.


2 Answers

Documentation states that you can only add handlers or configure the inner most handler to named or typed clients.

Reference Configure the HttpMessageHandler

It may be necessary to control the configuration of the inner HttpMessageHandler used by a client.

An IHttpClientBuilder is returned when adding named or typed clients. The ConfigurePrimaryHttpMessageHandler extension method can be used to define a delegate. The delegate is used to create and configure the primary HttpMessageHandler used by that client:

services.AddTransient<Handler1>();
services.AddTransient<Handler2>();

services.AddHttpClient("configured-inner-handler")
    .AddHttpMessageHandler<Handler1>()
    .AddHttpMessageHandler<Handler2>();
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        return new HttpClientHandler()
        {
            AllowAutoRedirect = false,
            UseDefaultCredentials = true
        };
    });
like image 103
Nkosi Avatar answered Oct 02 '22 16:10

Nkosi


Upon inspecting the source code of DefaultHttpClientFactory (which is both the IHttpClientFactory and the IHttpMessageHandlerFactory registered by AddHttpClient method), it turns out that there is no use registering a custom IHttpMessageHandlerFactory because DefaultHttpClientFactory never requires it (but directly uses its own method). Of course we could also register a custom IHttpClientFactory, but there is a easier way to achieve what we want.

The idea is that DefaultHttpClientFactory calls the transient service HttpMessageHandlerBuilder during its IHttpMessageHandlerFactory implementation, so all we have to do is to register a custom HttpMessageHandlerBuilder. For example:

public class CustomHttpMessageHandlerBuilder : HttpMessageHandlerBuilder {
    public override string Name { get; set; }
    public override HttpMessageHandler PrimaryHandler { get; set; }
    public override IList<DelegatingHandler> AdditionalHandlers => new List<DelegatingHandler>();
    // Our custom builder doesn't care about any of the above.
    public override HttpMessageHandler Build() {
        return new HttpClientHandler {
            // Our custom settings
        };
    }
}

And then register it:

services.AddTransient<HttpMessageHandlerBuilder, CustomHttpMessageHandlerBuilder>();

And it works.

like image 39
Mu-Tsun Tsai Avatar answered Oct 02 '22 15:10

Mu-Tsun Tsai