.Net Core 3.0 TimeSpan反序列化错误-.Net 5.0中已修复 [英] .Net Core 3.0 TimeSpan deserialization error - Fixed in .Net 5.0

查看:134
本文介绍了.Net Core 3.0 TimeSpan反序列化错误-.Net 5.0中已修复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.Net Core 3.0,并且需要使用Newtonsoft.Json反序列化以下字符串:

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

{
    "userId": null,
    "accessToken": null,
    "refreshToken": null,
    "sessionId": null,
    "cookieExpireTimeSpan": {
        "ticks": 0,
        "days": 0,
        "hours": 0,
        "milliseconds": 0,
        "minutes": 0,
        "seconds": 0,
        "totalDays": 0,
        "totalHours": 0,
        "totalMilliseconds": 0,
        "totalMinutes": 0,
        "totalSeconds": 0
    },
    "claims": null,
    "success": false,
    "errors": [
        {
            "code": "Forbidden",
            "description": "Invalid username unknown!"
        }
    ]
}

并遇到以下错误:

   Newtonsoft.Json.JsonSerializationException : Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.TimeSpan' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'cookieExpireTimeSpan.ticks', line 1, position 103.

读取HttpResponseMessage的内容时,实际上会发生错误字符串:

The error string actually happens when reading the content of HttpResponseMessage:

var httpResponse = await _client.PostAsync("/api/auth/login", new StringContent(JsonConvert.SerializeObject(new API.Models.Request.LoginRequest()), Encoding.UTF8, "application/json"));
var stringResponse = await httpResponse.Content.ReadAsStringAsync();

服务器控制器方法返回:

The server controller method returns:

return new JsonResult(result) { StatusCode = whatever; };

推荐答案

REST API服务不应产生这样的JSON字符串.我敢打赌,以前的版本会返回00:0:00而不是TimeSpan对象的所有属性.

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.

这样做的原因是.NET Core 3.0 System.Text.Json .此序列化器不支持TimeSpan .新的序列化器更快,在大多数情况下不会分配,但不会涵盖JSON.NET所做的所有 .

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.

无论如何,没有 no 标准方法来表示JSON中的日期或时间段.甚至ISO8601格式也是一种约定,而不是标准本身的一部分. JSON.NET使用可读格式(23:00:00),但是 ISO8601的持续时间格式看起来例如P23DT23H(23天23小时)或P4Y(4年).

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).

一种解决方案是回到JSON.NET.步骤在文档中进行了描述:

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

更新Startup.ConfigureServices以调用AddNewtonsoftJson.

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<TimeSpan>
{
    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());
    }
}

并使用AddJsonOptions将其注册在Startup.ConfigureServices中,例如:

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

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

这篇关于.Net Core 3.0 TimeSpan反序列化错误-.Net 5.0中已修复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆