gRPC for C# (.NET): Libraries, Setup, and Code Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

gRPC for C# (.NET): Libraries and Examples



gRPC is a modern high-performance remote procedure call (RPC) framework developed by Google. It uses HTTP/2 for transport and Protocol Buffers (protobuf) for data serialization. In the .NET ecosystem, gRPC has become the primary tool for building microservice architectures, providing strong typing, bidirectional streaming, and low latency. In this article, we will review the key libraries for working with gRPC in C# and provide practical examples.



Main Libraries for gRPC in .NET



The following NuGet packages are used for working with gRPC in .NET:



  • Grpc.Net.Client — client library for creating gRPC clients. It works on top of HttpClient and supports all call types: unary, server streaming, client streaming, and bidirectional streaming.
  • Grpc.AspNetCore.Server — server library for integrating gRPC into ASP.NET Core. It allows hosting gRPC services alongside regular REST APIs.
  • Google.Protobuf — library for working with Protocol Buffers, generating and deserializing messages.
  • Grpc.Tools — a set of tools for automatically generating C# code from .proto files during project build.


The development process includes three stages: describing the service in a .proto file, generating code, and implementing the server/client.



Example 1: Simple Unary Service (Request-Response)



Let's create a simple service for retrieving user information. To do this, define the user.proto file:



syntax = "proto3";

package user;

service UserService { rpc GetUser (UserRequest) returns (UserResponse);}

message UserRequest { int32 id = 1;}

message UserResponse { string name = 1; string email = 2; int32 age = 3;}


Add package references and the .proto file to the project. After building, the UserRequest, UserResponse classes and the UserServiceBase base class will be generated.



Server Implementation



using Grpc.Core;using User;

public class UserServiceImpl : UserService.UserServiceBase{ public override Task<UserResponse> GetUser(UserRequest request, ServerCallContext context) { var user = new UserResponse { Name = "Ivan Petrov", Email = "ivan@example.com", Age = 30 }; return Task.FromResult(user); }}


Starting the server in ASP.NET Core:



var builder = WebApplication.CreateBuilder(args);builder.Services.AddGrpc();var app = builder.Build();app.MapGrpcService<UserServiceImpl>();app.Run();


Client Implementation



using Grpc.Net.Client;using User;

var channel = GrpcChannel.ForAddress("https://localhost:5001");var client = new UserService.UserServiceClient(channel);

var response = await client.GetUserAsync(new UserRequest { Id = 1 });Console.WriteLine($"User: {response.Name}, Email: {response.Email}");


Example 2: Server Streaming



Server streaming is useful when you need to send a lot of data to the client, such as a list of events or logs. Let's extend our .proto file:



service UserService {  rpc GetUser (UserRequest) returns (UserResponse);  rpc ListUsers (Empty) returns (stream UserResponse);}

message Empty {}


Server implementation:



public override async Task ListUsers(Empty request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context){    var users = new List<UserResponse>    {        new UserResponse { Name = "Anna", Email = "anna@test.com" },        new UserResponse { Name = "Boris", Email = "boris@test.com" }    };

Recommendations