json.net: DateTimeStringConverter gets an already DateTime converted object in ReadJson()

偶尔善良 提交于 2021-01-13 09:35:27

问题


Prerequisites:

  • JSON.Net 11.0.2

I need to store the UTC DateTime round-trip date/time pattern via a JSON based REST-API.

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

So I wrote myself a DateTimeStringConverter to ensure no local culture information gets involved.

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;
    }
}

I was very confused as to why I was getting a DateTime object without the milliseconds. After a lot of trial and error, I got into it.

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 serves me an already converted DateTime object to deserialize on my own without any millisecond data. I didn't find any clues as to whether it is a bug or a feature.

To counter check it I wrote a 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 doesn't serve me an already converted bool object.

Is it a bug or is it a feature?


回答1:


This is a known behavior of Json.Net. Since JSON does not have a built-in syntax for denoting dates (like it does for booleans), they have to be represented as strings. By default Json.Net tries to be nice and parse date-looking strings for you.

If you are using your own converter for dates, or otherwise want to handle date parsing yourself, you need to be sure to set the DateParseHandling setting to None in the JsonSerializerSettings, otherwise the internal reader will try to handle it first.

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

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


来源:https://stackoverflow.com/questions/53508910/json-net-datetimestringconverter-gets-an-already-datetime-converted-object-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!