c# - Newtonsoft.Json v11 - DeserializeObject 抛出 JsonReaderException

标签 c# json json.net

我们已将 Newtonsoft.Json 从 10.0.3 升级到 11.0.1,之前可以运行的代码不再运行。

我们有以下 JSON:

[{"mail-type":"registration","response":"250 OK id=1UjnNr-gdf-C0 ","invoice-id":,"email":"testuser08@test.com"}]

然后我们调用下面的方法:

var events = JsonConvert.DeserializeObject<Event[]>(jsonEvents);

这在 10.0.3 上运行良好,但在 11.0.1 上不起作用。在此版本上抛出以下异常:

Exception thrown: 'Newtonsoft.Json.JsonReaderException' in Newtonsoft.Json.dll

Additional information: An undefined token is not a valid System.Nullable`1[System.Int64]. Path '[0].invoice-id', line 1.

我尝试将以下选项传递给 DeserializeObject

var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore,
    MissingMemberHandling = MissingMemberHandling.Ignore
};

但是还是一样的错误。必须进行哪些更改才能使其在 11.0.1 上运行。我担心我们无法容纳来自第三方 API 的 JSON 输出。

最佳答案

您的 JSON 样本格式不正确。如果我将你的 JSON 上传到 https://jsonlint.com/然后生成以下错误:

Error: Parse error on line 4:
...0 ",   "invoice-id": , "email": "testuse
----------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got ','

有问题的行如下:

"invoice-id": ,

根据JSON standard :, 之间需要有一个值。但是,为什么这在 Json.NET 10.0 中有效?显然这是一个错误,已修复。根据11.0.1 release notes :

Fix - Fixed not erroring when reading undefined for nullable long

因此,如果我们假设您的 Event 类型如下所示:

public partial class Event
{
    [JsonProperty("invoice-id")]
    public long? InvoiceId { get; set; }

    // Other properties as required
}

然后在 10.0 中,您的 JSON 可以使用此类型成功反序列化,但在 11.0 中则不能。但是,如果我们将 InvoiceId 更改为 int?:

public partial class Event
{
    [JsonProperty("invoice-id")]
    public int? InvoiceId { get; set; }

    // Other properties as required
}

两个版本都失败了。因此,修复似乎一直在处理 int?long?

理想情况下,您应该要求向您发送此类 JSON 的人对其进行修复,使其符合 http://www.json.org/ 所定义的格式。和 RFC 8259 .如果您仍然需要以与 Json.NET 10.0 相同的方式解析此类 JSON,则可以引入 TolerantNullableLongConverter,如下所示:

public class TolerantNullableLongConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(long?);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        if (reader.TokenType == JsonToken.Undefined)
            return null;
        if (reader.Value is long)
            return reader.Value;
        // string or int or decimal or ...
        return serializer.Deserialize<long>(reader);
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

并将其应用于您的类型,如下所示:

public partial class Event
{
    [JsonProperty("invoice-id")]
    [JsonConverter(typeof(TolerantNullableLongConverter))]
    public long? InvoiceId { get; set; }

    // Other properties as required
}

关于c# - Newtonsoft.Json v11 - DeserializeObject 抛出 JsonReaderException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49045501/

相关文章:

c# - 禁用表单的透明度

c# - 使用字符串值创建新实例

c# - 在 C# 中以编程方式生成决策表?

c# - 反序列化列表<struct>

c# - Newtonsoft.Json 试图猜测 token 类型并弄错了

c# - Newtonsoft.Json.JsonConvert.DeserializeObject 转换为 Newtonsoft.Json.Linq.JObject 问题

c# - 关于win应用程序c#中的缓存数据

php - 如何将其转换为数组?

json - 值不能为空。启动器中的参数名称 : connectionString appsettings. json

javascript - 我在进行 API 调用和接收 JSON 响应时遇到 JavaScript 问题