Data annotation validation for gRPC Code-First models in ASP.NET Core. Automatically validates request messages using System.ComponentModel.DataAnnotations attributes and returns structured validation errors via gRPC trailers. Optionally validate required reference type properties on request models. More info.
| Package | Description |
|---|---|
| Codify.GrpcCodeFirstDataAnnotations | Server-side interceptor that validates incoming gRPC requests |
| Codify.GrpcCodeFirstDataAnnotations.Exceptions | Client-side helper to read validation errors from gRPC RpcException trailers |
- Install the NuGet package:
dotnet add package Codify.GrpcCodeFirstDataAnnotations- Register services and enable the validation interceptor:
varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddGrpcDataAnnotationValidation();builder.Services.AddCodeFirstGrpc(options =>{options.EnableDataAnnotationValidation();});Optionally configure the validation behavior:
builder.Services.Configure<GrpcDataAnnotationValidationOptions>(options =>{// Experimental - in addition to DataAnnotations attributes, also validate `required` nullable reference type propertiesoptions.ValidateRequiredNullableProperties=true;// Log validation failures at Warning leveloptions.ValidationFailureLogLevel=LogLevel.Warning;});- Add
DataAnnotationsattributes to your request models:
[DataContract]publicclassCreatePersonRequest{[DataMember(Order=1)][Required][StringLength(50)]publicstringFirstName{get;set;}[DataMember(Order=2)][Required][EmailAddress]publicstringEmail{get;set;}[DataMember(Order=3)][Range(1,120)]publicintAge{get;set;}[DataMember(Order=4)][Range(typeof(TimeSpan),"00:30:00","08:00:00")]publicTimeSpanSessionDuration{get;set;}[DataMember(Order=5)]// Experimental - This property will be validated as well if `ValidateRequiredNullableProperties` is enabled, even without DataAnnotations attributespublicrequiredstringJob{get;set;}}When a request fails validation, the interceptor throws an RpcException with StatusCode.InvalidArgument and includes the validation errors as Base64-encoded JSON in the gRPC trailers.
- Install the client package:
dotnet add package Codify.GrpcCodeFirstDataAnnotations.Exceptions- Catch and read validation errors:
try{varresponse=awaitclient.CreatePersonAsync(request);}catch(RpcExceptionex){// Get the formatted error messagevarformattedMessage=ex.GetFormattedValidationErrors();Console.WriteLine(formattedMessage);// Optionally, get the structured validation errorsvarerrors=ex.GetValidationErrors();foreach(varerrorinerrors){Console.WriteLine($"{string.Join(", ",error.PropertyNames)}: {error.ErrorMessage}");}}Implement IDataAnnotationsResultHandler to customize how validation failures are processed:
publicclassMyCustomHandler:IDataAnnotationsResultHandler{publicTask<DataAnnotationValidationResult>HandleAsync(IList<ValidationResult>failures){// Custom logic here}}Register it before calling AddGrpcDataAnnotationValidation:
builder.Services.AddSingleton<IDataAnnotationsResultHandler,MyCustomHandler>();- Unary
- Server streaming
- Client streaming
- Duplex streaming
For streaming methods, each incoming message is validated as it is read.
See LICENSE for details.