我的目標是將從call web api取回的巢狀JSON轉成結構化的字串,顯示在畫面上。
網路上能輕易找到JSON反序列化(Deserialize)成Data Model Class Object的做法。反序列方法很強大,當Data Model Class是巢狀時,它能自動將巢狀JSON字串反列化成巢狀的Data Model Class Object。
不過,當我要將巢狀JSON字串轉成Key(欄位) : Value(值)這樣的字串,一行顯示一對,且要具有巢狀結構,這就需要自己寫了。
最後我完成的做法請看:【C#】【JSON】將JSON字串(巢狀、{開頭的、[開頭的...)解析(parse)為結構化的字串
本篇收錄的是我在思考JSON轉巢狀Dictionary時,找到的一些資料,留作參考。
摘自:Json.NET: Deserializing nested dictionaries
https://stackoverflow.com/questions/6416017/json-net-deserializing-nested-dictionaries
●這方法省code:
I had a very similar but slightly more complex need when I ran across this Q. At first I thought maybe I could adapt the accepted answer, but that seemed a bit complicated and I ended up taking a different approach. I was attempting to put a modern JSON layer on top of a legacy C++ API. I'll spare you the details of that, and just say the requirements boil down to:
JSON objects become Dictionary<string,object>
.
JSON arrays become List<object>
.
JSON values become the corresponding primitive CLR values.
The objects and arrays can be infinitely nested.
I first deserialize the request string into a Newtonsoft JSON object and then call my method to convert in accordance with the above requirements:
var jsonObject = JsonConvert.DeserializeObject(requestString);
var apiRequest = ToApiRequest(jsonObject);
// call the legacy C++ API ...
Here is my method that converts to the structure the API expects:
private static object ToApiRequest(object requestObject)
{
switch (requestObject)
{
case JObject jObject: // objects become Dictionary<string,object>
return ((IEnumerable<KeyValuePair<string, JToken>>) jObject).ToDictionary(j => j.Key, j => ToApiRequest(j.Value));
case JArray jArray: // arrays become List<object>
return jArray.Select(ToApiRequest).ToList();
case JValue jValue: // values just become the value
return jValue.Value;
default: // don't know what to do here
throw new Exception($"Unsupported type: {requestObject.GetType()}");
}
}
feedback:
This was really useful. I was unable to decode this kind of response with the given solution. {"id":2,"name":"root","descendants":[{"id":4,"name":"node2","descendants":[{"id":7,"name":"node21"},{"id":8,"name":"node22"}]},{"id":3,"name":"node1","descendants":[{"id":5,"name":"node11"},{"id":6,"name":"node12"}]}]}. Thanks – Pushpa Kumara May 28, 2021 at 11:56
●另一方法,供參考:
#region Nested Dictionary
//You will want to add null checks, and other exit cases otherwise you will quickly end up in an infinate loop.This is just to get you started.
public Dictionary<string, string> MapToDictionary(object source, string name)
{
var dictionary = new Dictionary<string, string>();
MapToDictionaryInternal(dictionary, source, name);
return dictionary;
}
private void MapToDictionaryInternal(Dictionary<string, string> dictionary, object source, string name)
{
var properties = source.GetType().GetProperties();
foreach (var p in properties)
{
var key = name + "." + p.Name;
object value = p.GetValue(source, null);
Type valueType = value.GetType();
if (valueType.IsPrimitive || valueType == typeof(String))
{
dictionary[key] = value.ToString();
}
else if (value is IEnumerable)
{
var i = 0;
foreach (object o in (IEnumerable)value)
{
MapToDictionaryInternal(dictionary, o, key + "[" + i + "]");
i++;
}
}
else
{
MapToDictionaryInternal(dictionary, value, key);
}
}
}
//Call it like this:
//Dictionary<string, string> dictionary2 = MapToDictionary(agreement, "Agreement");
#endregion
JToken和JObject有什么区别
一、JToken和JObject有什么区别
原文出处:JToken和JObject有什么区别 - 八英里 - 博客园
JObject 用于操作JSON对象
JArray 用语操作JSON数组
JValue 表示数组中的值
JProperty 表示对象中的属性,以"key/value"形式
JToken 用于存放Linq to JSON查询后的结果
二、(译)JToken的层次结构
原文地址:https://stackoverflow.com/questions/38558844/jcontainer-jobject-jtoken-and-linq-confusion/38560188#38560188?newreg=577582085c60496db7bdb78be26a2313
JToken的层次结构是这样的:
JToken -抽象基类
JContainer - 能够包含其它JToken的JToken抽象基类
JArray - 表示一个JSON数组(包含一个有序的List<JToken>)
JObeject - 表示一个JSON对象(包含一个IEnumerable<JProperty>)
JProperty - 表示一个JSON属性(在JObject中是一个name/JToken键值对)
JValue - 表示一个原生JSON值(string,number,boolean,null)
以下是几条基本的经验法则:
- 如果是一个对象(在JSON里是有大括号“{”和“}”来标识的),就用JObject。
- 如果是一个数组或集合(用中括号“[”和“]”标识的),就用JArray。
- 如果是原生值,就用JValue。
- 如果你不知道你的json是什么类型的token,或者你希望用一种通用的方式来处理上面任意一种类型的对象,就用JToken,然后你可以检查它的Type属性来决定是哪种类型的token,并把它转化成相应的类型。
三、 C# JTOKEN类的使用,实现解析动态JSON数据、遍历、查找
https://www.freesion.com/article/2598272928/
[C#][筆記] IEnumerable、IEnumerator 與 IEnumerable、IEnumerator
http://vegeee-csharp.blogspot.com/2017/02/c-ienumerableienumerator-ienumerable.html