JSON字典为空时,反序列化JSON字符串失败

编程入门 行业动态 更新时间:2024-10-17 23:35:38
本文介绍了JSON字典为空时,反序列化JSON字符串失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

当我尝试反序列化从第三方收到的json字符串(-我无法自己更改接收到的json字符串)时,我面临以下问题> Newtonsoft.Json :

Currently I'm facing the following issue when I try to deserialize a json string that I receive from a 3rd party (--> I cannot change the received json string by myself) with Newtonsoft.Json:

json包含一个字典(以及我在此处未列出的其他一些条目):

The json contains a dictionary (and some other entries that I don't list here):

"food": { "Menu 1": "abc", "Menu 2": "def" }

我创建了一个包含该属性(以及我在此处未列出的属性)的类:

I've created a class that contains the property (plus the properties that I didn't list here):

Dictionary<string, string> Food {get; set;}

在这种情况下,对json的反序列化工作正常. 食物为空时会发生此问题:

In this case the desiralization of the json works fine. The problem occurs when food is empty:

{ "food": [], }

在这种情况下,food似乎不是字典而是数组. 这就是为什么反序列化失败并显示以下错误的原因:

In this case it seems that food is not a dictionary but an array. That's the reason why the desirialization fails with the following error:

Newtonsoft.Json.JsonSerializationException:无法反序列化 当前的JSON数组(例如[1,2,3])转换为type 'System.Collections.Generic.Dictionary`2 [System.String,System.String]' 因为该类型需要一个JSON对象(例如{"name":"value"}) 正确反序列化.要解决此错误,请将JSON更改为 JSON对象(例如{"name":"value"})或将反序列化类型更改为 实现集合接口的数组或类型(例如 ICollection,IList),例如可以从JSON反序列化的List 大批.也可以将JsonArrayAttribute添加到类型中以强制将其 从JSON数组反序列化.路径食物"."

Newtonsoft.Json.JsonSerializationException: "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path 'food'."

请问有人可以帮助我解决这个问题吗?

Is anybody out there who can help me to solve this problem, please?

编辑 反序列化代码:

public T DeserializeAPIResults<T>(string json) { JObject obj = JsonConvert.DeserializeObject<JObject>(json); return obj.GetValue("canteen").ToObject<T>(); }

编辑2 带有值的完整json:

EDIT 2 Full json with values:

{ "canteen": [ { "name": "Canteen1", "src": "a link", "food": { "Menu 1": "abc", "Menu 2": "def", "Menu 3": "ghi", "Menu 4": "jkl", "Menu 5": "mno" } }, { "name": "Canteen2", "src": "a link", "food": { "Menu 1": "abc", "Menu 2": "def", "Menu 3": "ghi" } }, { "name": "Canteen3", "src": "a link", "food": { "Line 1": "abc", "Line 2": "def", "Line 3": "ghi" } } ] }

没有值的完整json:

Full json without values:

{ "canteen": [ { "name": "Canteen1", "src": "a link", "food": [], }, { "name": "Canteen2", "src": "a link", "food": [], }, { "name": "Canteen3", "src": "a link", "food": [], } ] }

编辑3 班级:

public sealed class Canteen { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("src")] public string Src { get; set; } [JsonProperty("food")] public Dictionary<string, string> Food { get; set; } public Canteen() { } }

方法调用:

Canteen[] canteens = DeserializeAPIResults<Canteen[]>(json);

推荐答案

如果特定键的值不固定且数据必须可配置,则Newtonsoft.json具有一个要在此处使用的功能,即[JsonExtensionData]. 了解详情

If your value for particular key are not fixed and data must be configurable then Newtonsoft.json has one feature that to be use here and that is [JsonExtensionData]. Read more

现在,序列化对象时将写入扩展数据.读写扩展数据可以自动往返所有JSON,而无需将所有属性添加到要反序列化的.NET类型中.仅声明您感兴趣的属性,然后让扩展数据完成其余工作.

Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.

当您的第三方json具有名称为food且其值为对象的密钥时,您正尝试反序列化为Dictionary<string, string> Food {get; set;},并且反序列化方法正确地反序列化json.

When your 3rd party json have an key with name food and its value as object then you are trying to deserialze into Dictionary<string, string> Food {get; set;} and your deserilization method correctly deserialize your json.

但是当food键具有数组时,您的方法无法反序列化,因为您正尝试将数组[]反序列化为string.

But when food key have array then your method fails to deserialize because you are trying to deserialize array [] into string.

如果您使用

[JsonExtensionData] public Dictionary<string, JToken> Food { get; set; }

代替

Dictionary<string, string> Food {get; set;}

然后您的反序列化工作.

Then your deserialization works.

所以最终您的课程将是

public sealed class Canteen { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("src")] public string Src { get; set; } [JsonExtensionData] public Dictionary<string, JToken> Food { get; set; } public Canteen() { } }

替代:

如果您在Canteen类中将Food属性数据类型声明为JToken,例如

If you declare your Food property data type to JToken in your Canteen class like

public sealed class Canteen { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("src")] public string Src { get; set; } [JsonProperty("food")] public JToken Food { get; set; } public Canteen() { } }

然后,无论food键是对象还是数组,您都可以成功反序列化json.

Then you can successfully deserialize your json whether your food key is either object or array.

然后,您可以从canteens数组访问每个食堂,并检索每个食堂的name,src和food键/值对.

And then you can access your each of canteen from canteens array and retrieve each canteen's name, src and food key/value pair like.

JToken的优点是您可以检查其类型是对象还是数组

The advantage of JToken is that you can check it's type whether its object or array

Canteen[] canteens = DeserializeAPIResults<Canteen[]>(json); foreach (var canteen in canteens) { string name = canteen.Name; string src = canteen.Src; JToken food = canteen.Food; if (food.Type == JTokenType.Object) { Dictionary<string, string> foods = food.ToObject<Dictionary<string, string>>(); } else if (food.Type == JTokenType.Array) { //Do something if "foods" is empty array "[]" } }

更多推荐

JSON字典为空时,反序列化JSON字符串失败

本文发布于:2023-11-17 02:33:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608489.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字符串   字典   为空   序列化   JSON

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!