For years Windows Communication Foundation (WCF) has been the de-facto framework for building RPCs in the .NET ecosytem. WCF enforced contract based development where the service will expose a contract which the client should adhere to (during compile time itself ) and SOAP messages were used to transport messages between server and client. With .NET Core (a cross platform .net implementation) v3.0 onwards, WCF services were not supported. That means any new service can’t be created using WCF. However, there is still support to consume WCF services from .NET Core 3.x apps.
But ASP.NET Core 3.0 brought in native support for gRPC which is one of the widely popular RPC frameworks built by Google. Support for gRPC from .NET Framework applications were always there, but it wasn’t really natively supported by .NET Framework. More details on this can be found here : https://grpc.io/blog/grpc-on-dotnetcore/
Some of the key concepts of gRPC are:
- gRPC by default uses Protocol Buffer as Interface Definition Language(IDL)
- gRPC uses HTTP/2 protocol
- gRPC supports below different types of RPC
- Unary RPC
- Server streaming RPC
- Client streaming RPC
- Bi-directional streaming RPC
In this blog post, I will provide a walk through of getting started with unary gRPC service & client using Visual Studio Code
Prerequisites :
- .NET Core 3.x SDK
- Visual Studio Code with C# extension on Windows
Step 1 : Create a new grpc
service using dotnet
CLI
Creating a new dotnet
core application is super simple. Just run the below command in commandline
C:\Blog>dotnet new grpc -o firstgRPCService The template "ASP.NET Core gRPC Service" was created successfully. Processing post-creation actions... Running 'dotnet restore' on firstgRPCService\firstgRPCService.csproj... Restore completed in 274.92 ms for C:\Blog\firstgRPCService\firstgRPCService.csproj. Restore succeeded.
Step 2 : Understand the code structure
Let’s explore some of the important changes/additions w.r.t grpc project template that enables grpc in aspnet core.
2.1 firstgRPCService.proj
file
greet.proto
is the protobuf file that defines the contract. This is the most important file as this is where all the contract (like models, methods) exposed by this service will be definedGrpc.AspNetCore
is the Nuget package that enables gRPC support for this aspnet core application
2.2 greet.proto
file
To work with protocol buffer files in Visual Code, we can use the vscode-proto3 extension. This extension makes it easy to edit .proto
files. You should see similar contents from the file as below:

syntax = "proto3"
– indicates the version of protocol buffer used
// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply); }
The above snippet defines the service. The service name is Greeter
and it exposes a unary rpc method SayHello
that takes a parameter of type HelloRequest
and responds a type HelloReply
. Below are the types definitions for HelloRequest & 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; }
2.3 Startup.cs
file
Startup.cs is where the aspnet core service configuration happens. AddGrpc
method enables grpc support for this aspnet core service
public void ConfigureServices(IServiceCollection services) { services.AddGrpc(); }
app.UseEndpoints(endpoints => { endpoints.MapGrpcService<GreeterService>(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("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"); }); });
GreeterService
is the .NET based service implementation of the greet.proto
file.Step 3 : Running the gRPC service
Execute the below command to run the service
C:\Blog\firstgRPCService>dotnet run info: Microsoft.Hosting.Lifetime[0] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Blog\firstgRPCService info: Microsoft.Hosting.Lifetime[0] Application is shutting down...
Browsing the URL https://localhost:5001
wil throw the below message in browser :
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
Step 4 : Creating a gRPC Client
gRPC client can be any dotnet or non-dotnet based application which supports http2 protocol. Invoking grpc services directly from browser based web apps is not possible (at the time of this writing) as the browsers don’t natively support http2
yet. There are other frameworks like grpc-web
which could help in those cases where grpc services can be invoked from JS directly. For this post, we will be creating a dotnet
core client
4.1 Let’s create a new console
application using the command
C:\Blog\firstgRPCClient>dotnet new console The template "Console Application" was created successfully. Processing post-creation actions... Running 'dotnet restore' on C:\Blog\firstgRPCClient\firstgRPCClient.csproj... Restore completed in 126.13 ms for C:\Blog\firstgRPCClient\firstgRPCClient.csproj. Restore succeeded.
4.2 Add necessary nuget packages for client app
Below are the nuget packages that are required by the console app to talk to grpc service
- Grpc.Net.Client – contains .NET Core client
- Google.Protobuf – to enable protobuf in the project
- Grpc.Tools – used while for tooling, especially while building the application
Run the below commands
C:\Blog\firstgRPCClient>dotnet add firstgRPCClient.csproj package Grpc.Net.Client C:\Blog\firstgRPCClient>dotnet add firstgRPCClient.csproj package Google.Protobuf C:\Blog\firstgRPCClient>dotnet add firstgRPCClient.csproj package Grpc.Tools
4.3 Add proto
files
We can copy the protos folder from the service project and paste it to the client project with the same path as protos/greet.proto
.
After this we need to include this under the firstgRPCClient.csproj as below
Note that, in this case we are making the GrpcServices as Client
whereas the server project will add it as server
This setting will enable the Grpc.Tools
to generate server and client specific code appropriately
4.4 Implement the gRPC Client
Building the project would create the GrpcGreeter
types from the proto file. Now update the Program.cs
file with the below main method implementation
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 = "Swaminathan Vetri" }); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
GrpcChannel
is the type that should be used to establish the communication between client and server listening at https://localhost:5001
Once the connection is established, we can create the client and then invoke the RPC methods by passing the required parameters
Step 5 : Testing the grpc service & client
Navigate to the grpc service folder in command prompt and run the command dotnet run
That should produce the output as follows :
C:\Blog\firstgRPCService>dotnet run info: Microsoft.Hosting.Lifetime[0] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Blog\firstgRPCService
Navigate to the grpc client folder in command prompt and run the command dotnet run
If the dotnet dev certs are not trusted yet in the machine, you might receive an error like this.
C:\Blog\firstgRPCClient>dotnet run Unhandled exception. Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Error starting gRPC call: The SSL connection could not be established, see inner exception.") at firstgRPCClient.Program.Main(String[] args) in C:\Blog\firstgRPCClient\Program.cs:line 15 at firstgRPCClient.Program.(String[] args)
To fix the above error, run the below command dotnet dev-certs https --trust
C:\Blog\firstgRPCClient>dotnet dev-certs https --trust Trusting the HTTPS development certificate was requested. A confirmation prompt will be displayed if the certificate was not previously trusted. Click yes on the prompt to trust the certificate. A valid HTTPS certificate is already present.
Now running the client project again, should succeed.
C:\Blog\firstgRPCClient>dotnet run Greeting: Hello Swaminathan Vetri Press any key to exit...
Well, we are done creating our first grpc unary service and a client! You can follow the same steps and add further proto
files and defined more models & service methods.
Thank you for sharing this well prepared article and the dotnet dev-certs https –trust tip; I ran into that error with Visual Studio Code.