Christophe Blin
Christophe Blin

Reputation: 1909

C# code first grpc : custom protobuf converter for DateTime

I'm using something like this in dotnet asp net core 6:

<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.152" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore.Reflection" Version="1.0.152" />


[DataContract]
public class TaskItem
{
    //other properties omitted

    [DataMember(Order = 5)]
    public DateTime DueDate { get; set; } = null!;
}

Now, when I call the service with grpcurl

"DueDate": {
  "value": "458398",
  "scale": "HOURS"
}

And in the generated proto file

import "protobuf-net/bcl.proto"; // schema for protobuf-net's handling of core .NET types

 message TaskItem {
    //other properties omitted
    .bcl.DateTime DueDate = 5;

Is there a way to specify a custom converter so that it will serialize to ISO 8601 string in order to better support cross platform (I'll have some clients in js where having a string is ok since I just need new Date(v) and d.toISOString()) ?

I know I can just declare DueDate as string, but then the "problem" is that when I use C# code-first client I also need to convert back to DateTime and to string ...

For example, I can do the following with JSON

.AddJsonOptions(x =>
{
    x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

Upvotes: 0

Views: 2881

Answers (1)

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131706

What you ask is very different from a JSON type converter. As the docs explain the standard way of serializing dates is the google.protobuf.Timestamp type. That's defined in the proto file. When you use code-first that file is generated by the open source protobuf-net.Grpc tool.

To use the Timestamp type you need to tell the tool to format that property using a well-known type with the ProtoMember attribute :

[ProtoMember(1, DataFormat = DataFormat.WellKnown)]
public DateTime Time { get; set; }

This is shown in the tool's Getting Started document.

This isn't the default for legacy reasons :

(for legacy reasons, protobuf-net defaults to a different library-specific layout that pre-dates the introduction of .google.protobuf.Timestamp). It is recommended to use DataFormat.WellKnown on DateTime and TimeSpan values whenever possible.

Upvotes: 1

Related Questions