gRPC services with ASP.NET Core
Note
This isn't the latest version of this article. For the current release, see the .NET 8 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see .NET and .NET Core Support Policy. For the current release, see the .NET 8 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 8 version of this article.
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
Visual Studio 2022 with the ASP.NET and web development workload.
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Program.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
// Add services to the container.
builder.Services.AddGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
IIS
Internet Information Services (IIS) is a flexible, secure and manageable Web Server for hosting web apps, including ASP.NET Core. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with IIS.
IIS must be configured to use TLS and HTTP/2. For more information, see Use ASP.NET Core with HTTP/2 on IIS.
HTTP.sys
HTTP.sys is a web server for ASP.NET Core that only runs on Windows. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with HTTP.sys.
HTTP.sys must be configured to use TLS and HTTP/2. For more information, see HTTP.sys web server HTTP/2 support.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
Visual Studio 2022 with the ASP.NET and web development workload.
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Program.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
// Add services to the container.
builder.Services.AddGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
IIS
Internet Information Services (IIS) is a flexible, secure and manageable Web Server for hosting web apps, including ASP.NET Core. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with IIS.
IIS must be configured to use TLS and HTTP/2. For more information, see Use ASP.NET Core with HTTP/2 on IIS.
HTTP.sys
HTTP.sys is a web server for ASP.NET Core that only runs on Windows. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with HTTP.sys.
HTTP.sys must be configured to use TLS and HTTP/2. For more information, see HTTP.sys web server HTTP/2 support.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
- Visual Studio 2022 with the ASP.NET and web development workload.
- .NET 6.0 SDK
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Program.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
using GrpcGreeter.Services;
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
// Add services to the container.
builder.Services.AddGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
IIS
Internet Information Services (IIS) is a flexible, secure and manageable Web Server for hosting web apps, including ASP.NET Core. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with IIS.
IIS must be configured to use TLS and HTTP/2. For more information, see Use ASP.NET Core with HTTP/2 on IIS.
HTTP.sys
HTTP.sys is a web server for ASP.NET Core that only runs on Windows. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with HTTP.sys.
HTTP.sys must be configured to use TLS and HTTP/2. For more information, see HTTP.sys web server HTTP/2 support.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
- Visual Studio 2019 16.8 or later with the ASP.NET and web development workload
- .NET 5.0 SDK
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Startup.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// Communication with gRPC endpoints must be made through a gRPC client.
// To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
endpoints.MapGrpcService<GreeterService>();
});
}
}
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
webBuilder.UseStartup<Startup>();
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
IIS
Internet Information Services (IIS) is a flexible, secure and manageable Web Server for hosting web apps, including ASP.NET Core. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with IIS.
IIS must be configured to use TLS and HTTP/2. For more information, see Use ASP.NET Core with HTTP/2 on IIS.
HTTP.sys
HTTP.sys is a web server for ASP.NET Core that only runs on Windows. .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later are required to host gRPC services with HTTP.sys.
HTTP.sys must be configured to use TLS and HTTP/2. For more information, see HTTP.sys web server HTTP/2 support.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
- Visual Studio 2019 16.4 or later with the ASP.NET and web development workload
- .NET Core 3.1 SDK
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Startup.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// Communication with gRPC endpoints must be made through a gRPC client.
// To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
endpoints.MapGrpcService<GreeterService>();
});
}
}
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
webBuilder.UseStartup<Startup>();
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
This document shows how to get started with gRPC services using ASP.NET Core.
Prerequisites
- Visual Studio 2019 with the ASP.NET and web development workload
- .NET Core 3.0 SDK
Get started with gRPC service in ASP.NET Core
View or download sample code (how to download).
See Get started with gRPC services for detailed instructions on how to create a gRPC project.
Add gRPC services to an ASP.NET Core app
gRPC requires the Grpc.AspNetCore package.
Configure gRPC
In Startup.cs
:
- gRPC is enabled with the
AddGrpc
method. - Each gRPC service is added to the routing pipeline through the
MapGrpcService
method.
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// Communication with gRPC endpoints must be made through a gRPC client.
// To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
endpoints.MapGrpcService<GreeterService>();
});
}
}
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
Server options
gRPC services can be hosted by all built-in ASP.NET Core servers.
- Kestrel
- TestServer
- IIS†
- HTTP.sys†
†Requires .NET 5 and Windows 11 Build 22000 or Windows Server 2022 Build 20348 or later.
For more information about choosing the right server for an ASP.NET Core app, see Web server implementations in ASP.NET Core.
Kestrel
Kestrel is a cross-platform web server for ASP.NET Core. Kestrel focuses on high performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.
Kestrel gRPC endpoints:
- Require HTTP/2.
- Should be secured with Transport Layer Security (TLS).
HTTP/2
gRPC requires HTTP/2. gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2
.
Kestrel supports HTTP/2 on most modern operating systems. Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.
TLS
Kestrel endpoints used for gRPC should be secured with TLS. In development, an endpoint secured with TLS is automatically created at https://localhost:5001
when the ASP.NET Core development certificate is present. No configuration is required. An https
prefix verifies the Kestrel endpoint is using TLS.
In production, TLS must be explicitly configured. In the following appsettings.json
example, an HTTP/2 endpoint secured with TLS is provided:
{
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
}
Alternatively, Kestrel endpoints can be configured in Program.cs
:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("<path to .pfx file>",
"<certificate password>");
});
});
webBuilder.UseStartup<Startup>();
});
For more information on enabling TLS with Kestrel, see Kestrel HTTPS endpoint configuration.
Protocol negotiation
TLS is used for more than securing communication. The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.
If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2
. An endpoint with multiple protocols, such as HttpProtocols.Http1AndHttp2
for example, can't be used without TLS because there's no negotiation. All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.
For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.
Note
macOS doesn't support ASP.NET Core gRPC with TLS before .NET 8. Additional configuration is required to successfully run gRPC services on macOS when using .NET 7 or earlier. For more information, see Unable to start ASP.NET Core gRPC app on macOS.
Host gRPC in non-ASP.NET Core projects
An ASP.NET Core gRPC server is typically created from the gRPC template. The project file created by the template uses Microsoft.NET.SDK.Web
as the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
The Microsoft.NET.SDK.Web
SDK value automatically adds a reference to the ASP.NET Core framework. The reference allows the app to use ASP.NET Core types required to host a server.
You can add a gRPC server to non-ASP.NET Core projects with the following project file settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
The preceding project file:
- Doesn't use
Microsoft.NET.SDK.Web
as the SDK. - Adds a framework reference to
Microsoft.AspNetCore.App
.- The framework reference allows non-ASP.NET Core apps, such as Windows Services, WPF apps, or WinForms apps to use ASP.NET Core APIs.
- The app can now use ASP.NET Core APIs to start an ASP.NET Core server.
- Adds gRPC requirements:
- NuGet package reference to
Grpc.AspNetCore
. .proto
file.
- NuGet package reference to
For more information about using the Microsoft.AspNetCore.App
framework reference, see Use the ASP.NET Core shared framework.
Integration with ASP.NET Core APIs
gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. For example, the service implementation can resolve a logger service from the DI container via the constructor:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).
Resolve HttpContext in gRPC methods
The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. Access is through the ServerCallContext
argument passed to each gRPC method:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
doesn't provide full access to HttpContext
in all ASP.NET APIs. The GetHttpContext
extension method provides full access to the HttpContext
representing the underlying HTTP/2 message in ASP.NET APIs:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
var clientCertificate = httpContext.Connection.ClientCertificate;
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
});
}
}
Additional resources
ASP.NET Core