Implementing gRPC Services in ASP.NET Core: A Complete Developer Guide

Implementing gRPC services in ASP.NET Core involves defining a Protocol Buffers contract, creating a service class that inherits from the generated C# base, and registering it with builder.Services.AddGrpc() and app.MapGrpcService<T>() in your application pipeline.

The dotnet/aspnetcore repository provides first-class infrastructure for building high-performance, contract-driven APIs using gRPC. Implementing gRPC services in ASP.NET Core follows a streamlined three-step workflow that leverages the framework's dependency injection, logging, and endpoint routing systems to create production-ready RPC endpoints.

Define the Service Contract with Protocol Buffers

Every gRPC service starts with a Protocol Buffers (.proto) file that defines the service API, message structures, and RPC method signatures. The gRPC tools generate a C# base class from this contract that your implementation inherits.

In the dotnet/aspnetcore repository, the template file at src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Protos/greet.proto demonstrates the standard structure:

syntax = "proto3";

option csharp_namespace = "GrpcService_CSharp";

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;
}

The csharp_namespace option ensures the generated code aligns with your project's namespace. When compiled, this produces a Greeter.GreeterBase class that serves as the foundation for your service implementation.

Implement the gRPC Service

With the contract defined, you implement the service by creating a class that derives from the generated base. According to the source code in src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Services/GreeterService.cs, implementations follow standard ASP.NET Core patterns including constructor injection for dependencies like ILogger<T>.

using Grpc.Core;

namespace GrpcService_CSharp.Services;

public class GreeterService(ILogger<GreeterService> logger) : Greeter.GreeterBase
{
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        logger.LogInformation("Received greeting request from {Name}", request.Name);

        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

Key implementation details:

  • Inheritance: Your class must inherit from the generated base (e.g., Greeter.GreeterBase)
  • Method overrides: Override the RPC methods defined in the proto file
  • Dependency injection: The constructor accepts ILogger<GreeterService> resolved from the DI container
  • ServerCallContext: Provides access to request metadata, deadlines, and cancellation tokens

Because the service runs inside the ASP.NET Core pipeline, you have full access to scoped services, configuration, and the HttpContext via ServerCallContext.

Register and Map the Service

The final step configures the ASP.NET Core host to recognize and expose your gRPC service. In src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.cs, the registration happens in two stages:

using GrpcService_CSharp.Services;

var builder = WebApplication.CreateBuilder(args);

// Register gRPC services.
builder.Services.AddGrpc();

var app = builder.Build();

// Expose the Greeter RPC.
app.MapGrpcService<GreeterService>();

// Simple fallback endpoint for browsers.
app.MapGet("/", () => 
    "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");

app.Run();

The registration process works as follows:

  1. AddGrpc(): Registers the gRPC server infrastructure (Grpc.AspNetCore.Server) and required services including IGrpcServerBuilder and IGrpcServiceActivator as implemented in the framework's service extensions.
  2. MapGrpcService<T>(): Creates an endpoint route for your service and wires it to the gRPC server. The runtime handles HTTP/2 connection management, message serialization, and error handling automatically.

The endpoint mapping supports HTTP/2 by default, with the runtime managing the protocol negotiation and stream multiplexing required by the gRPC specification.

Enable JSON Transcoding for HTTP/1.1 Clients

For scenarios requiring broader client compatibility, the ASP.NET Core gRPC stack supports JSON transcoding via AddJsonTranscoding(). This extension, defined in src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/GrpcJsonTranscodingServiceExtensions.cs, allows non-gRPC clients to call your service using standard JSON over HTTP/1.1.

builder.Services.AddGrpc()
                .AddJsonTranscoding(options =>
                {
                    // Configure descriptor registry or other options here.
                });

Benefits of JSON transcoding:

  • Browser compatibility: Call gRPC services from JavaScript without requiring gRPC-Web clients
  • Swagger integration: Generate OpenAPI documentation for your RPC endpoints
  • Legacy support: Enable existing HTTP/1.1 infrastructure to communicate with your service

This feature registers additional model binders that translate between JSON and Protocol Buffer messages without requiring changes to your service implementation.

Summary

Implementing gRPC services in ASP.NET Core combines contract-first development with the framework's robust DI and middleware pipeline:

  • Define contracts using .proto files to generate strongly-typed C# base classes

  • Implement services by inheriting from generated bases and leveraging constructor injection for ILogger<T> and other dependencies

  • Register services using AddGrpc() in Program.cs to configure the IGrpcServerBuilder infrastructure

  • Expose endpoints via MapGrpcService<T>() to create HTTP/2 routes handled by the gRPC server

  • Extend compatibility optionally with AddJsonTranscoding() to support JSON-over-HTTP clients

Frequently Asked Questions

How do I register a gRPC service in ASP.NET Core?

Register gRPC services in the Program.cs file by calling builder.Services.AddGrpc() to add the server infrastructure, then expose specific implementations using app.MapGrpcService<YourService>(). The AddGrpc() method registers the IGrpcServerBuilder and related activator services required to instantiate your service class per-request or as a singleton depending on its registration.

Can gRPC services use dependency injection in ASP.NET Core?

Yes, gRPC services support the same dependency injection patterns as controllers or minimal API endpoints. You can inject services through the constructor, as demonstrated by the ILogger<GreeterService> parameter in the GreeterService implementation. The framework resolves these dependencies from the DI container when creating the service instance via the IGrpcServiceActivator.

What is JSON transcoding in ASP.NET Core gRPC?

JSON transcoding is an optional feature that allows gRPC services to accept JSON requests over HTTP/1.1, translating them to Protocol Buffer messages automatically. Enable it by chaining .AddJsonTranscoding() after AddGrpc() in your service configuration. This extension, located in GrpcJsonTranscodingServiceExtensions.cs, is useful for browser clients or legacy systems that cannot support HTTP/2 and binary Protocol Buffers.

How do I handle logging in gRPC services?

Logging works identically to other ASP.NET Core services. Inject ILogger<T> into your service constructor and use standard logging methods like LogInformation(). The gRPC server implementation in GreeterService.cs shows this pattern, allowing you to capture request details, performance metrics, and diagnostic information through the standard ASP.NET Core logging pipeline.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →