Первый код С# grpc: пользовательский преобразователь protobuf для DateTime

Я использую что-то подобное в 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!;
}

Теперь, когда я вызываю службу с помощью grpcurl

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

И в сгенерированном прото файле

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

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

Есть ли способ указать собственный преобразователь, чтобы он сериализовался в строку ISO 8601, чтобы лучше поддерживать кросс-платформу (у меня есть несколько клиентов в js, где наличие строки в порядке, так как мне просто нужно new Date(v)а также d.toISOString()) ?

Я знаю, что могу просто объявить DueDate как строку, но тогда «проблема» заключается в том, что когда я использую код первого клиента С#, мне также нужно преобразовать обратно в DateTime и в строку...

Например, я могу сделать следующее с JSON

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

1 ответ

То, что вы спрашиваете, сильно отличается от конвертера типов JSON. Поскольку документы объясняют, что стандартным способом сериализации дат является google.protobuf.Timestampтип. Это определено в protoфайл. При использовании code-first этот файл создается инструментом protobuf-net.Grpc с открытым исходным кодом .

Чтобы использовать Timestampтипа, вам нужно указать инструменту отформатировать это свойство, используя хорошо известный тип с ProtoMemberатрибут :

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

Это показано в документе « Приступая к работе» инструмента .

Это не значение по умолчанию по устаревшим причинам:

(по устаревшим причинам protobuf-net по умолчанию использует другой макет для конкретной библиотеки, который предшествует появлению .google.protobuf.Timestamp). По возможности рекомендуется использовать DataFormat.WellKnown для значений DateTime и TimeSpan.

Другие вопросы по тегам