Newtonsoft.Json v11 - DeserializeObject抛出JsonReaderException
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Newtonsoft.Json v11 - DeserializeObject抛出JsonReaderException相关的知识,希望对你有一定的参考价值。
我们已经将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上没有。在此版本上抛出以下异常:
抛出异常:Newtonsoft.Json.dll中的'Newtonsoft.Json.JsonReaderException'
附加信息:未定义的令牌不是有效的System.Nullable`1 [System.Int64]。路径'[0] .invoice-id',第1行。
我试图将以下选项传递给DeserializeObject
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
但仍然是同样的错误。必须进行哪些更改才能使其在11.0.1上运行。我担心我们无法容纳JSON输出,因为它来自第三方API。
您的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:
修复 - 修复了在为可空的长度读取undefined时没有错误
因此,如果我们假设您的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
}
您可以使用自定义转换器实施变通方法:
internal class NullableLongFixupConverter : JsonConverter {
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
writer.WriteValue(value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
// if token undefined - return null
if (reader.TokenType == JsonToken.Undefined)
return null;
// otherwise - value
return (long?) reader.Value;
}
public override bool CanConvert(Type objectType) {
return objectType == typeof(long?);
}
}
然后你可以用它来装饰属性:
class Event {
[JsonProperty("invoice-id")]
[JsonConverter(typeof(NullableLongFixupConverter))]
public long? InvoiceId { get; set; }
}
或全局注册(仅对long?
类型的属性调用):
JsonConvert.DefaultSettings = () =>
{
var s = new JsonSerializerSettings();
s.Converters.Add(new NullableLongFixupConverter());
return s;
};
以上是关于Newtonsoft.Json v11 - DeserializeObject抛出JsonReaderException的主要内容,如果未能解决你的问题,请参考以下文章
FineUI中Newtonsoft.Json版本报错解决办法
无法将类型“newtonsoft.json.linq.jtoken”隐式转换为 newt“newtonsoft.json.linq.jvalue”
从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”