gRPC services with C#
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.
This document outlines the concepts needed to write gRPC apps in C#. The topics covered here apply to both C-core-based and ASP.NET Core-based gRPC apps.
proto file
gRPC uses a contract-first approach to API development. Protocol buffers (protobuf) are used as the Interface Definition Language (IDL) by default. The .proto
file contains:
- The definition of the gRPC service.
- The messages sent between clients and servers.
For more information on the syntax of protobuf files, see Create Protobuf messages for .NET apps.
For example, consider the greet.proto file used in Get started with gRPC service:
- Defines a
Greeter
service. - The
Greeter
service defines aSayHello
call. SayHello
sends aHelloRequest
message and receives aHelloReply
message:
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
Add a .proto
file to a C# app
The .proto
file is included in a project by adding it to the <Protobuf>
item group:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
By default, a <Protobuf>
reference generates a concrete client and a service base class. The reference element's GrpcServices
attribute can be used to limit C# asset generation. Valid GrpcServices
options are:
Both
(default when not present)Server
Client
None
C# Tooling support for .proto
files
The tooling package Grpc.Tools is required to generate the C# assets from .proto
files. The generated assets (files):
- Are generated on an as-needed basis each time the project is built.
- Aren't added to the project or checked into source control.
- Are a build artifact contained in the obj directory.
This package is required by both the server and client projects. The Grpc.AspNetCore
metapackage includes a reference to Grpc.Tools
. Server projects can add Grpc.AspNetCore
using the Package Manager in Visual Studio or by adding a <PackageReference>
to the project file:
<PackageReference Include="Grpc.AspNetCore" Version="2.32.0" />
Client projects should directly reference Grpc.Tools
alongside the other packages required to use the gRPC client. The tooling package isn't required at runtime, so the dependency is marked with PrivateAssets="All"
:
<PackageReference Include="Google.Protobuf" Version="3.18.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.40.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Generated C# assets
The tooling package generates the C# types representing the messages defined in the included .proto
files.
For server-side assets, an abstract service base type is generated. The base type contains the definitions of all the gRPC calls contained in the .proto
file. Create a concrete service implementation that derives from this base type and implements the logic for the gRPC calls. For the greet.proto
, the example described previously, an abstract GreeterBase
type that contains a virtual SayHello
method is generated. A concrete implementation GreeterService
overrides the method and implements the logic handling the gRPC call.
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
For client-side assets, a concrete client type is generated. The gRPC calls in the .proto
file are translated into methods on the concrete type, which can be called. For the greet.proto
, the example described previously, a concrete GreeterClient
type is generated. Call GreeterClient.SayHelloAsync
to initiate a gRPC call to the server.
// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
By default, server and client assets are generated for each .proto
file included in the <Protobuf>
item group. To ensure only the server assets are generated in a server project, the GrpcServices
attribute is set to Server
.
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
Similarly, the attribute is set to Client
in client projects.
Additional resources
This document outlines the concepts needed to write gRPC apps in C#. The topics covered here apply to both C-core-based and ASP.NET Core-based gRPC apps.
proto file
gRPC uses a contract-first approach to API development. Protocol buffers (protobuf) are used as the Interface Definition Language (IDL) by default. The .proto
file contains:
- The definition of the gRPC service.
- The messages sent between clients and servers.
For more information on the syntax of protobuf files, see Create Protobuf messages for .NET apps.
For example, consider the greet.proto file used in Get started with gRPC service:
- Defines a
Greeter
service. - The
Greeter
service defines aSayHello
call. SayHello
sends aHelloRequest
message and receives aHelloReply
message:
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.
Add a .proto
file to a C# app
The .proto
file is included in a project by adding it to the <Protobuf>
item group:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
By default, a <Protobuf>
reference generates a concrete client and a service base class. The reference element's GrpcServices
attribute can be used to limit C# asset generation. Valid GrpcServices
options are:
Both
(default when not present)Server
Client
None
C# Tooling support for .proto
files
The tooling package Grpc.Tools is required to generate the C# assets from .proto
files. The generated assets (files):
- Are generated on an as-needed basis each time the project is built.
- Aren't added to the project or checked into source control.
- Are a build artifact contained in the obj directory.
This package is required by both the server and client projects. The Grpc.AspNetCore
metapackage includes a reference to Grpc.Tools
. Server projects can add Grpc.AspNetCore
using the Package Manager in Visual Studio or by adding a <PackageReference>
to the project file:
<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />
Client projects should directly reference Grpc.Tools
alongside the other packages required to use the gRPC client. The tooling package isn't required at runtime, so the dependency is marked with PrivateAssets="All"
:
<PackageReference Include="Google.Protobuf" Version="3.11.4" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.28.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Generated C# assets
The tooling package generates the C# types representing the messages defined in the included .proto
files.
For server-side assets, an abstract service base type is generated. The base type contains the definitions of all the gRPC calls contained in the .proto
file. Create a concrete service implementation that derives from this base type and implements the logic for the gRPC calls. For the greet.proto
, the example described previously, an abstract GreeterBase
type that contains a virtual SayHello
method is generated. A concrete implementation GreeterService
overrides the method and implements the logic handling the gRPC call.
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
For client-side assets, a concrete client type is generated. The gRPC calls in the .proto
file are translated into methods on the concrete type, which can be called. For the greet.proto
, the example described previously, a concrete GreeterClient
type is generated. Call GreeterClient.SayHelloAsync
to initiate a gRPC call to the server.
static async Task Main(string[] args)
{
// The port number(5001) must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
By default, server and client assets are generated for each .proto
file included in the <Protobuf>
item group. To ensure only the server assets are generated in a server project, the GrpcServices
attribute is set to Server
.
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
Similarly, the attribute is set to Client
in client projects.