aspnetcore/grpc/grpcweb/includes/grpcweb6-7.md
:::moniker range=">= aspnetcore-6.0 < aspnetcore-8.0"
Learn how to configure an existing ASP.NET Core gRPC service to be callable from browser apps, using the gRPC-Web protocol. gRPC-Web allows browser JavaScript and Blazor apps to call gRPC services. It's not possible to call an HTTP/2 gRPC service from a browser-based app. gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC.
For instructions on adding a gRPC service to an existing ASP.NET Core app, see Add gRPC services to an ASP.NET Core app.
For instructions on creating a gRPC project, see xref:tutorials/grpc/grpc-start.
There are two choices for how to add gRPC-Web to an ASP.NET Core app:
Grpc.AspNetCore.Web package.There are pros and cons to each approach. If an app's environment is already using Envoy as a proxy, it might make sense to also use Envoy to provide gRPC-Web support. For a basic solution for gRPC-Web that only requires ASP.NET Core, Grpc.AspNetCore.Web is a good choice.
gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC. gRPC-Web doesn't require any changes to services. The only modification is in setting the middelware in Program.cs.
To enable gRPC-Web with an ASP.NET Core gRPC service:
Grpc.AspNetCore.Web package.UseGrpcWeb and EnableGrpcWeb to Program.cs::::code language="csharp" source="~/grpc/grpcweb/sample/7.x/GrpcGreeter/Program.cs" id="snippet_WebEnable" highlight="9,11":::
The preceding code:
UseGrpcWeb, after routing and before endpoints.endpoints.MapGrpcService<GreeterService>() method supports gRPC-Web with EnableGrpcWeb.Alternatively, the gRPC-Web middleware can be configured so that all services support gRPC-Web by default and EnableGrpcWeb isn't required. Specify new GrpcWebOptions { DefaultEnabled = true } when the middleware is added.
:::code language="csharp" source="~/grpc/grpcweb/sample/8.x/GrpcGreeter/Program.cs" id="snippet_WebEnableAllServices" highlight="9":::
[!NOTE] There is a known issue that causes gRPC-Web to fail when hosted by HTTP.sys in .NET Core 3.x.
A workaround to get gRPC-Web working on HTTP.sys is available in Grpc-web experimental and UseHttpSys()? (grpc/grpc-dotnet #853).
Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction applies to making gRPC-Web calls with browser apps. For example, a browser app served by https://www.contoso.com is blocked from calling gRPC-Web services hosted on https://services.contoso.com. Cross-Origin Resource Sharing (CORS) can be used to relax this restriction.
To allow a browser app to make cross-origin gRPC-Web calls, set up CORS in ASP.NET Core. Use the built-in CORS support, and expose gRPC-specific headers with xref:Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicyBuilder.WithExposedHeaders%2A.
:::code language="csharp" source="~/grpc/grpcweb/sample/8.x/GrpcGreeter/Program.cs" id="snippet_WebEnableCORS" highlight="7-13,18,21":::
The preceding code:
AddCors to add CORS services and configure a CORS policy that exposes gRPC-specific headers.UseCors to add the CORS middleware after routing configuration and before endpoints configuration.endpoints.MapGrpcService<GreeterService>() method supports CORS with RequireCors.Traditional gRPC over HTTP/2 supports client, server and bidirectional streaming. gRPC-Web offers limited support for streaming:
When using gRPC-Web, we only recommend the use of unary methods and server streaming methods.
The ASP.NET Core gRPC service template, included in the .NET SDK, creates an app that's only configured for HTTP/2. This is a good default when an app only supports traditional gRPC over HTTP/2. gRPC-Web, however, works with both HTTP/1.1 and HTTP/2. Some platforms, such as UWP or Unity, can't use HTTP/2. To support all client apps, configure the server to enable HTTP/1.1 and HTTP/2.
Update the default protocol in appsettings.json:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Alternatively, configure Kestrel endpoints in startup code.
Enabling HTTP/1.1 and HTTP/2 on the same port requires TLS for protocol negotiation. For more information, see ASP.NET Core gRPC protocol negotiation.
Browser apps can use gRPC-Web to call gRPC services. There are some requirements and limitations when calling gRPC services with gRPC-Web from the browser:
A JavaScript gRPC-Web client exists. For instructions on how to use gRPC-Web from JavaScript, see write JavaScript client code with gRPC-Web.
The .NET gRPC client can be configured to make gRPC-Web calls. This is useful for Blazor WebAssembly apps, which are hosted in the browser and have the same HTTP limitations of JavaScript code. Calling gRPC-Web with a .NET client is the same as HTTP/2 gRPC. The only modification is how the channel is created.
To use gRPC-Web:
Grpc.Net.Client.Web package.Grpc.Net.Client package is version 2.29.0 or later.GrpcWebHandler::::code language="csharp" source="~/grpc/grpcweb/sample/8.x/GrpcGreeterClient/Program.cs" id="snippet_Handler":::
The preceding code:
GrpcWebHandler has the following configuration options:
InnerHandler: The underlying xref:System.Net.Http.HttpMessageHandler that makes the gRPC HTTP request, for example, HttpClientHandler.GrpcWebMode: An enumeration type that specifies whether the gRPC HTTP request Content-Type is application/grpc-web or application/grpc-web-text.
GrpcWebMode.GrpcWeb configures sending content without encoding. Default value.GrpcWebMode.GrpcWebText configures base64-encoded content. Required for server streaming calls in browsers.HttpVersion: HTTP protocol Version used to set xref:System.Net.Http.HttpRequestMessage.Version?displayProperty=nameWithType on the underlying gRPC HTTP request. gRPC-Web doesn't require a specific version and doesn't override the default unless specified.[!IMPORTANT] Generated gRPC clients have synchronous and asynchronous methods for calling unary methods. For example,
SayHellois synchronous, andSayHelloAsyncis asynchronous. Asynchronous methods are always required in Blazor WebAssembly. Calling a synchronous method in a Blazor WebAssembly app causes the app to become unresponsive.
Create a .NET client compatible with gRPC-Web using the gRPC client factory:
AddGrpcClient extension method. In a Blazor WebAssembly app, services are registered with DI in Program.cs.GrpcWebHandler using the xref:Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.ConfigurePrimaryHttpMessageHandler%2A extension method.builder.Services
.AddGrpcClient<Greet.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(
() => new GrpcWebHandler(new HttpClientHandler()));
For more information, see xref:grpc/clientfactory.
:::moniker-end