问题
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