Разрешить неверную дату в ASP.NET Core API Service - PullRequest
0 голосов
/ 15 ноября 2018

У нас есть служба API, которую мы обновляем, и мы преобразовали некоторые объекты даты из строк в объекты DateTime. В старом коде мы тестировали строку, если она будет анализировать время данных или нет. Если это была неверно отформатированная строка, она присваивает DateTime.Min и продолжает работу. Теперь клиенты отправляют плохие даты, и это взрывается, поскольку сериализация происходит вне нашего кода (MVC Controller). Я пытаюсь найти способ, которым при сериализации объекта DateTime, если он не может его проанализировать, он просто возвращает DateTime.Min вместо взрыва вызова.

Вот ответ от API Call.

{
  "date": [
    "Could not convert string to DateTime: Invalid Date. Path 'date', line 3, position 24."
  ]
}

===== ОБНОВЛЕНИЕ =====

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

Пользовательский конвертер

  public class DateConverter : JsonConverter
  {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      try
      {
        return DateTime.Parse(reader.Value.ToString());
      }
      catch (Exception ex)
      {
        return DateTime.MinValue;
      }
    }

    public override bool CanConvert(Type objectType)
    {
      return objectType == typeof(DateTime);
    }
  }

Класс DTO

public class Request
  {

    [JsonConverter(typeof(SafeDateConverter))]
    public DateTime Date { get; set; }
  }

1 Ответ

0 голосов
/ 15 ноября 2018

Другой подход - ввести другое свойство десериализованного класса типа DateTime? и оставить исходное свойство строки без изменений.

public class Request
{
    public string Date { get; set; }

    private DateTime? _parsedDate;
    [JsonIgnore]
    public DateTime? ParsedDate 
    { 
        get { return _parsedDate; } 
        set
        {
            if (DateTime.TryParse(value, out DateTime parsed)
            {
                _parsedDate = parsed;
                return;
            }

            _parsed = null;
        }
    }       
}

Но наличие собственного сериализатора выглядит лучше, потому что вам не нужно ничего менять в коде, который уже использует десериализованный объект.

Предложение:
Не используйте try ... catch для сериализации неверно отформатированных дат, есть метод DateTime.TryParse, который сделает это без исключения.

И если еще не поздно, вы можете использовать Nullable<DateTime> вместо значения DateTime.Min в качестве "несуществующего" значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...