refit icon indicating copy to clipboard operation
refit copied to clipboard

[BUG] The 'InnerHandler' property must be null.

Open jchannon opened this issue 3 years ago • 6 comments

Using the code defined in the README https://github.com/reactiveui/refit#reducing-header-boilerplate-with-delegatinghandlers-authorization-headers-worked-example, running the app results in an exception:

Unexpected application termination! "The 'InnerHandler' property must be null. 'DelegatingHandler' instances provided to 'HttpMessageHandlerBuilder' must not be reused or cached.\nHandler: 'Easee.Connector.AuthHeaderHandler'"
System.InvalidOperationException: The 'InnerHandler' property must be null. 'DelegatingHandler' instances provided to 'HttpMessageHandlerBuilder' must not be reused or cached.
Handler: 'Easee.Connector.AuthHeaderHandler'
   at HttpMessageHandler Microsoft.Extensions.Http.HttpMessageHandlerBuilder.CreateHandlerPipeline(HttpMessageHandler primaryHandler, IEnumerable<DelegatingHandler> additionalHandlers)
   at HttpMessageHandler Microsoft.Extensions.Http.DefaultHttpMessageHandlerBuilder.Build()
   at ActiveHandlerTrackingEntry Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(string name)
   at ActiveHandlerTrackingEntry Microsoft.Extensions.Http.DefaultHttpClientFactory+<>c__DisplayClass14_0.<.ctor>b__1(?)+() => { }
   at void System.Lazy<T>.ViaFactory(LazyThreadSafetyMode mode)
   at void System.Lazy<T>.ExecutionAndPublication(LazyHelper executionAndPublication, bool useDefaultConstructor)
   at T System.Lazy<T>.CreateValue()
   at T System.Lazy<T>.get_Value()
   at HttpMessageHandler Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(string name)
   at HttpClient Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(string name)

Steps To Reproduce

Expected behavior My app to run.

I believe you shouldn't set the InnerHandler

Environment

  • OS: macOS 12.5
  • .NET Core: 6

jchannon avatar Aug 17 '22 19:08 jchannon

This still seems to be an issue - when using RestService.For - the code works, but when using Dependency Injection (HttpClientFactory) the code fails. I was able to work around it using => AuthorizationHeaderValueGetter.

MarkEnverus avatar Oct 10 '22 13:10 MarkEnverus

As @jchannon said, the inner handler should not be set when using from DI or it will fail when building the handlers pipeline

Ninja2 avatar Oct 31 '22 12:10 Ninja2

@Ninja2 should we update the docs to reflect this? It's confusing and then you need separate setups for either RestService.For and DI?

MarkEnverus avatar Oct 31 '22 15:10 MarkEnverus

I can confirm this issue when implementing on Azure Functions.

  • Assigning the InnerHander throws an exception with DI
  • NOT assigning the InnerHandler throws an exception with RestService.For

In case others end here as me ( and the issue isn't closed ;) )

My current workaround is to add a flag in the DelegatingHandler constructor e.g.

      public RequestInterceptor(ILogger log, bool useDependencyInjection = true)
      {
        Logger = log;

        if(useDependencyInjection)
            return;

        var handler = new HttpClientHandler
        {
            // what ever
        };

        InnerHandler = handler;
     }

Hence for DI (Azure Functions):

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        var logger = builder.Services
            .AddRefitClient<Iapi>()
            .ConfigureHttpClient(httpClient => httpClient.BaseAddress = new Uri(<url>))
            .AddHttpMessageHandler(serviceProvider => new RequestInterceptor(serviceProvider.GetService<ILogger<RequestInterceptor>>()));
    }
}

For RestService.For (Testing):

RestService.For<Iapi>(new HttpClient(new RequestInterceptor(new Mock<ILogger>().Object, false)) { BaseAddress = new Uri(<url>) });

noontz avatar Apr 06 '23 17:04 noontz

I m facing the same issue in a MAUI Blazor App .Net 7.0 in my app there are two messages handlers one for SSL Pinning as follow


public class HttpsValidation : HttpClientHandler
{
public HttpsValidation()
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli;
    UseProxy = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
   
    ServerCertificateCustomValidationCallback = OnValidateCertificate;
}
}

and a DelegatingHandler message handler for httpclient request as follow

public class CustomHttpRequestHandler : DelegatingHandler
{

}

I m injecting httpsclient as follow

builder.Services.AddHttpClient<HttpClient>(
    "MyhttpClient",
    client => client.BaseAddress = new Uri(BaseUrl)
    ).ConfigureHttpMessageHandlerBuilder(builder => builder.PrimaryHandler = new HttpClientHandler()
    {
        UseDefaultCredentials = true
    }
    ).ConfigurePrimaryHttpMessageHandler(() => new HttpsValidation())
    .AddHttpMessageHandler<CustomHttpRequestHandler>();

Really the app is working fine but sometimes this issue appears suddenly even sometimes when the app is idle for a while I get this error as follow

blazor.webview.js:1 The 'InnerHandler' property must be null. 'DelegatingHandler' instances provided to 'HttpMessageHandlerBuilder' must not be reused or cached. Handler: 'CustomHttpRequestHandler '

salghazaly avatar Nov 23 '23 06:11 salghazaly

any status update here?

rsr-maersk avatar Dec 13 '23 13:12 rsr-maersk

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Jul 05 '24 00:07 github-actions[bot]