Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the .NET and .NET Core Support Policy. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
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 Create a .NET Core gRPC client and server in ASP.NET Core.
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 middleware in Program.cs
.
To enable gRPC-Web with an ASP.NET Core gRPC service:
Grpc.AspNetCore.Web
package.UseGrpcWeb
and EnableGrpcWeb
to Program.cs
:using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.UseGrpcWeb();
app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps using the gRPC-Web protocol");
app.Run();
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.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps using the gRPC-Web protocol");
app.Run();
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 WithExposedHeaders.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));
var app = builder.Build();
app.UseGrpcWeb();
app.UseCors();
app.MapGrpcService<GreeterService>().EnableGrpcWeb()
.RequireCors("AllowAll");
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps using the gRPC-Web protocol");
app.Run();
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
:var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
The preceding code:
GrpcWebHandler
has the following configuration options:
InnerHandler
: The underlying 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 HttpRequestMessage.Version 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, SayHello
is synchronous, and SayHelloAsync
is 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 ConfigurePrimaryHttpMessageHandler extension method.builder.Services
.AddGrpcClient<Greet.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(
() => new GrpcWebHandler(new HttpClientHandler()));
For more information, see gRPC client factory integration in .NET.
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 Create a .NET Core gRPC client and server in ASP.NET Core.
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
:using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.UseGrpcWeb();
app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps using the gRPC-Web protocol");
app.Run();
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.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps using the gRPC-Web protocol");
app.Run();
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 WithExposedHeaders.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));
var app = builder.Build();
app.UseGrpcWeb();
app.UseCors();
app.MapGrpcService<GreeterService>().EnableGrpcWeb()
.RequireCors("AllowAll");
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps using the gRPC-Web protocol");
app.Run();
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
:var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
The preceding code:
GrpcWebHandler
has the following configuration options:
InnerHandler
: The underlying 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 HttpRequestMessage.Version 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, SayHello
is synchronous, and SayHelloAsync
is 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 ConfigurePrimaryHttpMessageHandler extension method.builder.Services
.AddGrpcClient<Greet.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(
() => new GrpcWebHandler(new HttpClientHandler()));
For more information, see gRPC client factory integration in .NET.
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 Create a .NET Core gRPC client and server in ASP.NET Core.
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 startup configuration.
To enable gRPC-Web with an ASP.NET Core gRPC service:
Grpc.AspNetCore.Web
package.UseGrpcWeb
and EnableGrpcWeb
to Startup.cs
:public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
});
}
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.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
});
}
}
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 WithExposedHeaders.
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseGrpcWeb();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb()
.RequireCors("AllowAll");
});
}
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
:var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
The preceding code:
GrpcWebHandler
has the following configuration options:
InnerHandler
: The underlying 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 HttpRequestMessage.Version 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, SayHello
is synchronous, and SayHelloAsync
is 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 ConfigurePrimaryHttpMessageHandler extension method.builder.Services
.AddGrpcClient<Greet.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(
() => new GrpcWebHandler(new HttpClientHandler()));
For more information, see gRPC client factory integration in .NET.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreTraining
Module
Implement HTTP operations in ASP.NET Core Blazor Web apps - Training
Implement HTTP operations in ASP.NET Core Blazor Web apps
Documentation
gRPC services with ASP.NET Core
Learn the basic concepts when writing gRPC services with ASP.NET Core.
Troubleshoot errors when using gRPC on .NET.
Migrate gRPC from C-core to gRPC for .NET
Learn how to move an existing C-core based gRPC app to run on top of gRPC for .NET.