json.net: DateTimeStringConverter получает уже преобразованный объект DateTime в ReadJson () - PullRequest
0 голосов
/ 28 ноября 2018

Предварительные условия:

  • JSON.Net 11.0.2

Мне нужно сохранить шаблон даты / времени UTC DateTime в обоих направлениях через REST-API на основе JSON.

string utcTimestamp = DateTime.UtcNow.ToString( "o" );
// 2018-11-27T22:35:32.1234567Z

Итак, я написал себе DateTimeStringConverter, чтобы гарантировать, что информация о местной культуре не будет задействована.

class DateTimeStringConverter:
    JsonConverter<DateTime>
{
    public override void WriteJson( JsonWriter writer, DateTime value, JsonSerializer serializer )
    {
        string convertedValue = value.ToString( "o" );
        writer.WriteValue( convertedValue );
    }

    public override DateTime ReadJson( JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer )
    {
        string value = reader.Value.ToString( );
        DateTime convertedValue = DateTime.Parse( value ).ToLocalTime( );
        return convertedValue;
    }
}

Я был очень озадачен тем, почему я получил DateTimeобъект без миллисекунд.После долгих проб и ошибок я понял:

public override DateTime ReadJson( JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer )
{
    Console.WriteLine( reader.Value.GetType( ).ToString( ) );
    // System.DateTime

    string value = reader.Value.ToString( );
    DateTime convertedValue = DateTime.Parse( value ).ToLocalTime( );
    return convertedValue;
}

JSON.Net предоставляет мне уже преобразованный объект DateTime для десериализации самостоятельно без каких-либо миллисекундных данных.Я не нашел никаких подсказок относительно того, является ли это ошибкой или функцией.

Чтобы проверить это, я написал BooleanStringConverter.

class BoolStringConverter:
    JsonConverter<bool>
{
    public override void WriteJson( JsonWriter writer, bool value, JsonSerializer serializer )
    {
        string convertedValue = false == value ? "False" : "True";
        writer.WriteValue( convertedValue );
    }

    public override bool ReadJson( JsonReader reader, Type objectType, bool existingValue, bool hasExistingValue, JsonSerializer serializer )
    {
        Console.WriteLine( reader.Value.GetType( ).ToString( ) );
        // System.String

        string value = ( string ) reader.Value;
        bool convertedValue = "False" == value ? false : true;
        return convertedValue;
    }
}

JSON.Net неподайте мне уже преобразованный bool объект.

Это ошибка или особенность?

1 Ответ

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

Это известное поведение Json.Net.Поскольку JSON не имеет встроенного синтаксиса для обозначения дат (как это имеет место для логических значений), они должны быть представлены в виде строк.По умолчанию Json.Net старается быть удобной и анализировать строки, которые выглядят как даты.

Если вы используете свой собственный конвертер для дат или иным образом хотите обрабатывать данные самостоятельно, вам нужно обязательно установитьDateParseHandling, установленный на None в JsonSerializerSettings, в противном случае внутренний считыватель попытается обработать его первым.

JsonSerializerSettings settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new DateTimeStringConverter() },
    DateParseHandling = DateParseHandling.None
};

var foo = JsonConvert.DeserializeObject<Foo>(json, settings);
...