После портирования ASP.NET Core 2.2 на 3.0 запрос DateTime не десериализован должным образом и выдает ошибку - PullRequest
0 голосов
/ 26 сентября 2019

Я портирую простой веб-API с asp.net core 2.2 на asp.net core 3.0 и получаю ошибку сериализации после отправки запроса к действию.

Не удалось преобразовать значение JSON в System.DateTime.Путь: $ .DateOfBirth |Номер строки: 6 |BytePositionInLine: 28.

Контракт (запрос) данных не изменился: я буквально скопировал запрос DTO из одного решения в другое, и в DTO существуют те же аннотации данных, как показано ниже.

        [Required]
    public DateTime DateOfBirth { get; set; }

Это поле json запроса

    "DateOfBirth": "01/01/1980",

Почему asp.net core 2.2 способен правильно десериализовать это, а asp.net core 3.0 нет?Есть идеи?

Для нового проекта asp.net core 3.0 я использую

    <PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" />

Если бы я мог изменить значение поля json на такой формат, как

1980-01-01T00:00:00

Я больше не получаю ошибку.Однако я не могу изменить значение поля json, отправленное клиентами, поскольку у меня есть много клиентских приложений, которые зависят от веб-API и координируют это изменение, что будет длительным процессом.Поэтому мне нужно сохранить контракт таким же.

Я нашел следующий текст из https://docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support

Попытка десериализации представлений, которые не соответствуют профилю, заставит JsonSerializer выдать исключение JsonException:

Мне нужно обойти это, поскольку я не могу изменить то, что отправляет клиентское приложение.

1 Ответ

0 голосов
/ 27 сентября 2019

Это будет работать в краткосрочной перспективе для решения

            services.AddControllers().AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
        });

и

    public class DateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        Debug.Assert(typeToConvert == typeof(DateTime));
        return DateTime.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"));
    }
}
...