I’m excited to announce experimental support for gRPC-Web with .NET. gRPC-Web allows gRPC to be called from browser-based apps like JavaScript SPAs or Blazor WebAssembly apps.
gRPC-Web for .NET promises to bring many of gRPC’s great features to browser apps:
- Strongly-typed code-generated clients
- Compact Protobuf messages
- Server streaming
What is gRPC-Web
It is impossible to implement the gRPC HTTP/2 spec in the browser because there is no browser API with enough fine-grained control over HTTP requests. gRPC-Web solves this problem by being compatible with HTTP/1.1 and HTTP/2.
gRPC-Web is not a new technology. There is a stable gRPC-Web JavaScript client, and a proxy for translating between gRPC and gRPC-Web for services. The new experimental packages allow an ASP.NET Core gRPC app to support gRPC-Web without a proxy, and allow the .NET Core gRPC client to call gRPC-Web services. (great for Blazor WebAssembly apps!)
New opportunites with gRPC-Web
- Call ASP.NET Core gRPC apps from the browser – Browser APIs can’t call gRPC HTTP/2. gRPC-Web offers a compatible alternative.
- JavaScript SPAs
- .NET Blazor Web Assembly apps
- Host ASP.NET Core gRPC apps in IIS and Azure App Service – Some servers, such as IIS and Azure App Service, currently can’t host gRPC services. While this is actively being worked on, gRPC-Web offers an interesting alternative that works in every environment today.
- Call gRPC from non-.NET Core platforms – Some .NET platforms
HttpClient
doesn’t support HTTP/2. gRPC-Web can be used to call gRPC services on these platforms (e.g. Blazor WebAssembly, Xamarin).
Note that there is a small performance cost to gRPC-Web, and two gRPC features are no longer supported: client streaming and bi-directional streaming. (server streaming is still supported!)
Server gRPC-Web instructions
If you are new to gRPC in .NET, there is a simple tutorial to get you started.
gRPC-Web does not require any changes to your services, the only modification is startup configuration. To enable gRPC-Web with an ASP.NET Core gRPC service, add a reference to the Grpc.AspNetCore.Web package. Configure the app to use gRPC-Web by adding AddGrpcWeb(...)
and UseGrpcWeb()
in the startup file:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
// Add gRPC-Web middleware after routing and before endpoints
app.UseGrpcWeb();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
});
}
Some additional configuration may be required to call gRPC-Web from the browser, such as configuring the app to support CORS.
Client gRPC-Web instructions
The JavaScript gRPC-Web client has instructions for setting up a gRPC-Web client to use in browser JavaScript SPAs.
Calling gRPC-Web with a .NET client is the same as regular gRPC, the only modification is how the channel is created. To enable gRPC-Web, add a reference to the Grpc.Net.Client.Web package. Configure the channel to use the GrpcWebHandler
:
// Configure a channel to use gRPC-Web
var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpClient = new HttpClient(handler)
});
var client = Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new GreeterRequest { Name = ".NET" });
To see gRPC-Web with .NET in action, take a moment to read a great blog post written by Steve Sanderson that uses gRPC-Web in Blazor WebAssembly.
Try gRPC-Web with ASP.NET Core today
Preview packages are on NuGet:
- Grpc.AspNetCore.Web – Add gRPC-Web support to an ASP.NET Core gRPC service.
- Grpc.Net.Client.Web – Call gRPC-Web endpoints from .NET
Documentation for using gRPC-Web with .NET Core can be found here.
gRPC-Web for .NET is an experimental project, not a committed product. We want to test that our approach to implementing gRPC-Web works, and get feedback on whether this approach is useful to .NET developers compared to the traditional way of setting up gRPC-Web via a proxy. Please add your feedback here or at the https://github.com/grpc/grpc-dotnet to ensure we build something that developers like and are productive with.
Thanks!
James, can you bring us up to date on the status of gRPC-Web and Blazor Client please? Perhaps a new blog as we’re getting closer to Blazor client release?
Thanks!
..Ben
I successfully managed to get a grpc-web service working using Kestrel, but then attempted to convert it to using Http.sys (not under IIS), but I've tried and failed to get it working, always getting a "The response headers cannot be modified because the response has already starteed." invalid operation exception.
Am I completely barking up the wrong tree - does this experiment not support http.sys in this way?
A little frustrated - this is exactly the use...
Hi i try to use this from Xamarin forms and it work when i publish the server to azure but i am not able to debug on local dev computer from Android.
i have tested to follow the instruction on thttps://go.microsoft.com/fwlink/?linkid=2099682.
so i add this on the client side.
handlerdev = new HttpClientHandler();
handlerdev.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
...
Is there a sample project for this? In my attempt, the server is returning 200 after a couple of seconds, but the client is reporting a 404 after a few milliseconds. I’m assuming I’ve got something setup wrong, but I’ve been scratching my head over it.
Example project here – https://github.com/grpc/grpc-dotnet/tree/master/examples#blazor
Blazor and Browser both use gRPC-Web.
Managed to get a stripped down version working – https://github.com/ThatRickGuy/WASM-Blazor-gRPC-Sample
Not sure what’s going on with my full version yet, but there appears to be an issue if you call the gRPC service synchronously. The server responds as expected, but the browser never completes the call, it just chews up the CPU and hangs.
We've already got some gRPC clients (Dotnet Core Worker Service) running using reverse proxies and Kestrel, but are keen to switch to App Service Plans (or even a VM and IIS) as this is the business standard approach. As such, this post was a great bit of news and so we quickly set about converting the start up in both client and server to support it.
Having deployed to both VM running IIS and then an...
Hi, You mention that gRPC-Web will work with IIS before I commit some time what would be the correct way of hosting the gRPC Service on IIS?
There are no special requirements for gRPC-Web on IIS. It works with HTTP/1.1 and HTTP/2. It works with TLS and without TLS.
I have tested this in IIS, but the client just waits on
SayHelloAsync
. If you shutdown the server however then you get 404.Hi!
I was impatient to use gRPC in a Browser, gRPC-Web with ASP.NET Core made it real, I have been able to build an Angular 8 app with gRPC-Web.
Thank you! I really enjoy the feature, I would love to use that in production.
Here is the repository of the Angular 8 app: https://github.com/AnthonyGiretti/angular8-grpc-aspnetcore3-1-demo
Thanks for the article, it was very helpful.
I've been trying to get a Grpc Server to Stream to a Blazor WebAssembly application without luck. The examples for Blazer only show a Unary call, not a streaming example.
My attempts at adding this show a stream coming through in the network (via Chrome dev tools) but the code isn't picking it up in the Blazor Web app. I've made sure the HttpClient is in GrpcWebText...
I have the same behavior on my program, impossible to operate the server streaming mode, I hope it will be implemented before the release of version 2.27
I tested out server streaming in Blazor WA and also ran into problems. There is a problem in Blazor’s HttpClient implementation.
There is a workaround to get server streaming working here – https://github.com/mono/mono/issues/18718#issuecomment-582667900
Is it possible to generate proto files from my C# contract. I am new to GRPC but not new to C#. I would like the ability define my C# contract and generate a proto file from that.
That’s outside the scope of the work we are doing.
protobuf-net uses C# types as the contract. They might support it, or consider supporting it. You could ask about that feature here – https://github.com/protobuf-net/protobuf-net
Same question here.
WOW Zeeshan are you alive? Used to read your articles and books. Good to see you around! What’s your handle?
I also wonder what about inheritance, validation logic or other shared entity implementations.
Looks great! Are there any plans to support model (proto) validation? gRPC looks promising but the lack of model validation is which normal ASP/ViewModels provides is making me hesitant to make the switch.
I have created an issue for that here – https://github.com/grpc/grpc-dotnet/issues/741