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.
Create a contract first
Create a blank solution. Add new “Class Library (.NET standard)” project with name “Contract”.
Add required packages
- System.ServiceModel.Primitives, which contains ServiceContractAttribute and OperationContractAttribute
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 reference to the “Contract” project
- add reference to ServiceModel.Grpc.AspNetCore
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
- add reference to the “Contract” project
- add reference to Grpc.Core
- add reference to ServiceModel.Grpc
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.