ServiceModel.Grpc

Code-first for gRPC

View on GitHub

ServiceModel.Grpc Create a gRPC client and server in ASP.NET Core

This tutorial shows how to create a .NET client and an ASP.NET Core Server. In the end, you’ll have a gRPC client that communicates with the gRPC Greeter service.

View sample code.

Create a contract first

Create a blank solution. Add new “Class Library (.NET standard)” project with name “Contract”.

Add required packages

Add class Person

Person is decorated for data contract serialization.

using System.Runtime.Serialization;

namespace Contract
{
    [DataContract]
    public class Person
    {
        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string SecondName { get; set; }
    }
}

Add service contract

Contract is decorated with ServiceContractAttribute and OperationContractAttribute.

using System.ServiceModel;
using System.Threading;
using System.Threading.Tasks;

namespace Contract
{
    [ServiceContract]
    public interface IGreeter
    {
        [OperationContract]
        Task<string> SayHelloAsync(string personFirstName, string personSecondName, CancellationToken token = default);

        [OperationContract]
        Task<string> SayHelloToAsync(Person person, CancellationToken token = default);
    }
}

Create service

Add new “ASP.NET Core Web Application” project with name “Service”. In the wizard select “Empty (an empty project template…)” and un-check “Configure for HTTPS”.

Add required references

Add Greeter service

using System.Threading;
using System.Threading.Tasks;
using Contract;

namespace Service
{
    internal sealed class Greeter : IGreeter
    {
        public Task<string> SayHelloAsync(string personFirstName, string personSecondName, CancellationToken token)
        {
            return Task.FromResult(string.Format("Hello {0} {1}", personFirstName, personSecondName));
        }

        public Task<string> SayHelloToAsync(Person person, CancellationToken token)
        {
            return Task.FromResult(string.Format("Hello {0} {1}", person.FirstName, person.SecondName));
        }
    }
}

Configure ServiceModel.Grpc

In the Program.cs register ServiceModel.Grpc

var builder = WebApplication.CreateBuilder();

// register ServiceModel.Grpc
builder.Services.AddServiceModelGrpc();

// ....

Bind Greeter

In the Program.cs bind Greeter service

var app = builder.Build();

// bind Greeter service
app.MapGrpcService<Greeter>();

Configure http2

http2 is a precondition for gRPC commination protocol.

In the Program.cs add appsettings.json to the configuration

var builder = WebApplication.CreateBuilder();

builder.Configuration.SetBasePath(AppContext.BaseDirectory);
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false);

appsettings.json instructs Kestrel to listen Http2 on port 5000

"Kestrel": {
    "Endpoints": {
        "default": {
        "Url": "http://*:5000",
        "Protocols": "Http2"
        }
    }
}

In the “Service” project properties -> Debug tab -> Profile select “Service”. By default “IIS Express” is selected.

Create client

Add new “Console App (.NET Core)” project with name “Client”.

Add required references

Make application entry point async

public static class Program
{
    public static async Task Main(string[] args)
    {
    }
}

Configure ServiceModel.Grpc client factory

In the Program.cs, create static link to ServiceModel.Grpc.Client.ClientFactory

public static class Program
{
    private static readonly IClientFactory DefaultClientFactory = new ClientFactory();
}

Create gRPC channel

To create a channel you have to know a port of “Service” application. You can find or change it in the Service\Properties\launchSettings.json.

By default when you run Service application the url from “Service” is used. In this example the port is 5000.

var channel = new Channel("localhost", 5000, ChannelCredentials.Insecure);

Create client calls

public static class Program
{
    private static readonly IClientFactory DefaultClientFactory = new ClientFactory();

    public static async Task Main(string[] args)
    {
        // create gRPC channel
        var channel = new Channel("localhost", 50516, ChannelCredentials.Insecure);

        // create IGreeter client proxy
        var client = DefaultClientFactory.CreateClient<IGreeter>(channel);

        var person = new Person { FirstName = "John", SecondName = "X" };

        var greet1 = await client.SayHelloAsync(person.FirstName, person.SecondName);
        Console.WriteLine(greet1);

        var greet2 = await client.SayHelloToAsync(person);
        Console.WriteLine(greet2);
   }
}

Run application

Run “Service” and then “Client”

What is next

Customize error handling.