question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Issue when using GrpcClient with HttpClientFactory on .NET 6

See original GitHub issue

What version of gRPC and what language are you using?

<PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />

What operating system (Linux, Windows,…) and version?

Windows 11

What runtime / compiler are you using (e.g. .NET Core SDK version dotnet --info)

.NET 6.0.100

What did you do?

I just followed the guidance from MS docs to create the client and server using gRPC. The server part runs fine without errors. But the client whenever I add the code below

builder.Services
    .AddGrpcClient<Auditor.AuditorClient>("Auditor", o =>
    {
        o.Address = new Uri("https://localhost:5006");
    })
    .ConfigureHttpClient(client => /* <=== This will cause the exception */
    {
    })
    .EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);

What did you expect to see?

I expect the client part should run fine with the ConfigureHttpClient function in-place

What did you see instead?

The exception

System.InvalidOperationException: The ConfigureHttpClient method is not supported when creating gRPC clients. Unable to create client with name 'Auditor'.
   at Grpc.Net.ClientFactory.Internal.DefaultGrpcClientFactory.CreateClient[TClient](String name)
   at SalePayment.StateMachines.OrderStateMachine..ctor(GrpcClientFactory grpcClientFactory) in D:\github\northwind-dotnet\SalePayment\StateMachines\OrderStateMachine.cs:line 12
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at MassTransit.ExtensionsDependencyInjectionIntegration.Registration.DependencyInjectionContainerRegistrar.<>c__5`2.<MassTransit.Registration.IContainerRegistrar.RegisterSagaStateMachine>b__5_0(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
JamesNKcommented, Nov 11, 2021

Great.

Thanks for the feedback. I’ve improved the doc some more: https://github.com/dotnet/AspNetCore.Docs/pull/23857

0reactions
thangchungcommented, Nov 11, 2021

Hi @JamesNK and @adityamandaleeka ,

I would like to confirm that after following the docs that you wrote, then it works. But with some of the changes so that I put it here for someone who has got the issue just like me

gRPC Server

We have set up the server with some lines of codes as

using System.Net;
using AuditCenter.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();
builder.WebHost.ConfigureKestrel((context, options) =>
{
    options.Listen(IPAddress.Any, 5001, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http3;
        listenOptions.UseHttps();
    });
});

var app = builder.Build();

app.UseHttpLogging();

// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcService<AuditService>();
app.MapGet("/",
    () =>
        "AuditService is ready to serve you!!! What do you want from me?");

app.Run();

And after the run, it should run at https://localhost:5001. And we might need to trust the server using dotnet dev-certs https --trust

gRPC Client

The client should follow some steps:

  • Step 1: Open up the client.csproj, and add
<ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Net.SocketsHttpHandler.Http3Support" Value="true" />
</ItemGroup>

The docs for it can be found at https://docs.microsoft.com/en-us/dotnet/core/extensions/httpclient-http3#using-httpclient

  • Step 2: Adding some code for configuration like you mentioned
public class Http3Handler : DelegatingHandler
{
    public Http3Handler(HttpMessageHandler innerHandler)
        : base(innerHandler)
    {
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Version = HttpVersion.Version30;
        request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
        return base.SendAsync(request, cancellationToken);
    }
}

And configure for gRPC Client

builder.Services
    .AddGrpcClient<Auditor.AuditorClient>("Auditor", o =>
    {
        o.Address = new Uri("https://localhost:5001");
    })
    .ConfigureChannel(options =>
    {
        options.HttpHandler = new Http3Handler(new HttpClientHandler());
    })
    .EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);

And now we can run it perfectly.

Thank you again for the guidance and shed the light on it @JamesNK 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

gRPC client factory integration in .NET
Learn how to create gRPC clients using the client factory. ... gRPC integration with HttpClientFactory offers a centralized way to create ...
Read more >
A Deep Dive into Working with gRPC in .NET 6
AspNetCore.Server.ClientFactory: This package supports the integration of HTTPClientFactory for gRPC .NET clients in ASP.NET Core applications.
Read more >
c# - is it possible to instance as singleton a http client with ...
The performance heavy task seems to be the re-creation of gRPC channels, which use the HttpClientMessageHandler type.
Read more >
ASP.NET Core 6: Here is the best way to pass a JWT in ...
NET 6 allows you to attach a delegate (which can be asynchronous) to a gRPC type client which allows you to automatically manipulate...
Read more >
Using HttpClientFactory in ASP.NET Core Applications
Let's learn how to use HttpClientFactory in .NET Core applications. Also, we will learn how to use Named and Typed client instances.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found