Добавление пользовательского JsonConverter в Web API влияет на строковое значение, передаваемое в пользовательский атрибут проверки - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть ASP. NET Web API, который принимает json запросов. Используется JsonMediaTypeFormatter по умолчанию.

configuration.Formatters.Add(new JsonMediaTypeFormatter());

В модели я использую пользовательский атрибут ValidationAttribute, чтобы обеспечить соответствие строкового значения ожидаемому формату даты и времени. Пример допустимого значения = "2020-04-21T11: 30: 43 + 03: 00"

Фрагмент кода из моей модели (который, очевидно, содержит много других свойств):

[Required]
[DateFormat("yyyy-MM-ddTHH:mm:sszzz")]
public string RegistrationTimestamp { get; set; }

public string RegisteredValue { get; set; }

Фрагмент кода из атрибута DateFormat ValidationAttribute, показанного ниже:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    if (value == null)
    {
        return ValidationResult.Success;
    }

    if (DateTime.TryParseExact((string)value, _dateFormat, new CultureInfo("nl-NL"), DateTimeStyles.AdjustToUniversal, out DateTime date))
    {
        return ValidationResult.Success;
    }

    return new ValidationResult($"Date provided [{AntiXssEncoder.HtmlEncode(value.ToString(), true)}] is not formatted as [{_dateFormat}].");
}

Сказанное выше работает нормально.

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

Конфигурация настроена:

configuration.Formatters.Add(new JsonMediaTypeFormatter());
configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new EmptyStringToNullConverter());

Реализован пользовательский JsonConverter:

public class EmptyStringToNullConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)    
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null)
        {
            return null;
        }

        var text = reader.Value.ToString();

        if (string.IsNullOrWhiteSpace(text))
        {
            return null;
        }

        return text;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotSupportedException("Not needed because this converter cannot write json");
    }

    public override bool CanWrite
    {
        get { return false; }
    }
}

Лог c JsonConverter работает нормально, и это гарантирует, что пустая строка преобразуется в ноль. К сожалению, добавление этого JsonConverter, по-видимому, влияет на интерпретацию строковых значений, поскольку значение, передаваемое атрибуту DateFormat ValidationAttribute, больше не является строковым значением, предоставленным API, но изменилось с "2020-04-21T11: 30: 43 + 03: 00 "into" 21-Apr-20 10:30:43 ".

Как добавление пользовательского JsonConverter может повлиять на значение, передаваемое в атрибут ValidationAttribute, если этот пользовательский JsonConvertor ничего не делает для анализа даты?

1 Ответ

0 голосов
/ 23 апреля 2020

По-видимому, я не первый, кто столкнулся с этой проблемой, как я узнал, просматривая проблемы GitHub на Newtonsoft. Json пакет: https://github.com/JamesNK/Newtonsoft.Json/issues/904

Так что в конечном итоге В итоге я установил для DateParseHandling значение None, сохранив свой собственный JsonConvertor.

configuration.Formatters.Add(new JsonMediaTypeFormatter());
configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new EmptyStringToNullConverter());
configuration.Formatters.JsonFormatter.SerializerSettings.DateParseHandling = DateParseHandling.None;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...