.Net Core 3.0 TimeSpan deserialization error - Fixed in .Net 5.0

后端 未结 3 2174
抹茶落季
抹茶落季 2021-02-13 23:27

I am using .Net Core 3.0 and have the following string which I need to deserialize with Newtonsoft.Json:

{
    \"userId\": null,
    \"accessToken\": null,
    \         


        
3条回答
  •  清歌不尽
    2021-02-13 23:38

    The REST API service shouldn't produce such a JSON string. I'd bet that previous versions returned 00:0:00 instead of all the properties of a TimeSpan object.

    The reason for this is that .NET Core 3.0 replaced JSON.NET with a new, bult-in JSON serializer, System.Text.Json. This serializer doesn't support TimeSpan. The new serializer is faster, doesn't allocate in most cases, but doesn't cover all the cases JSON.NET did.

    In any case, there's no standard way to represent dates or periods in JSON. Even the ISO8601 format is a convention, not part of the standard itself. JSON.NET uses a readable format (23:00:00), but ISO8601's duration format would look like P23DT23H (23 days, 23 hours) or P4Y (4 years).

    One solution is to go back to JSON.NET. The steps are described in the docs:

    • Add a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson.

    • Update Startup.ConfigureServices to call AddNewtonsoftJson.

    services.AddMvc()
        .AddNewtonsoftJson();
    

    Another option is to use a custom converter for that type, eg :

    public class TimeSpanToStringConverter : JsonConverter
    {
        public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value=reader.GetString();
            return TimeSpan.Parse(value);
        }
    
        public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    

    And register it in Startup.ConfigureServices with AddJsonOptions, eg :

    services.AddControllers()                    
            .AddJsonOptions(options=>
                options.JsonSerializerOptions.Converters.Add(new TimeSpanToStringConverter()));
    
    

提交回复
热议问题