我想获取一些Json并将其解析为键/值对的集合,但有些值本身就是字典。我尝试了通常的牛顿软件反序列化。它很接近,但不太正确。最终结果必须是字典,而不是强类型类。
这是一些示例 Json:
{
"JobNumber": 1010,
"Asset": null,
"JobNotes": [
{
"NoteText": "It's not working.",
"NoteType": "Complaint"
},
{
"NoteText": "Needs to be fixed",
"NoteType": "Job"
}
]
}
这是我用来反序列化的代码:
var json = File.ReadAllText(@"c:tempjob.json");
var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
结果几乎是正确的,但带有"JobNotes"键的项目的值只是 json 字符串。我希望解析器递归并将内部 Json 反序列化为字符串和对象的进一步字典。有没有办法用牛顿软件库做到这一点?或者,是否有另一个库可以做到这一点?是否可以挂接到解析方法以覆盖该时间点的功能?
@DanielKeogh代码的修改版本。效果很好。
class Program
{
static void Main(string[] args)
{
var json = File.ReadAllText(@"c:tempjob3.json");
var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
RecurseDeserialize(result);
}
private static void RecurseDeserialize(Dictionary<string, object> result)
{
//Iterate throgh key/value pairs
foreach (var keyValuePair in result.ToArray())
{
//Check to see if Newtonsoft thinks this is a JArray
var jarray = keyValuePair.Value as JArray;
if (jarray != null)
{
//We have a JArray
//Convert JArray back to json and deserialize to a list of dictionaries
var dictionaries = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jarray.ToString());
//Set the result as the dictionary
result[keyValuePair.Key] = dictionaries;
//Iterate throught the dictionaries
foreach (var dictionary in dictionaries)
{
//Recurse
RecurseDeserialize(dictionary);
}
}
}
}
}
这个修改后的 Json 显示了它的深度:
{
"JobNumber": 1010,
"Asset": null,
"JobNotes": [
{
"NoteText": "It's not working.",
"NoteType": "Complaint"
},
{
"NoteText": "Needs to be fixed",
"NoteType": "Job",
"JobNoteNotes": [
{
"Something": 1,
"Something2": "Test"
}
]
}
]
}
结果结束了三个字典,以便我可以通过键获取"Something"值。
这可以通过一点递归来完成。我将把定义IsJson
留给你作为学术练习。:)
Dictionary<string, object> RecursiveDeserialize(string json)
{
var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
foreach (var pair in result.ToArray())
{
if(IsJson(pair.Value))
{
result[pair.Key] = RecursiveDeserialize(pair.Value);
}
}
return result;
}
将此对象用于 json 字符串
public class JobNote
{
public string NoteText { get; set; }
public string NoteType { get; set; }
}
public class ListJob
{
public int JobNumber { get; set; }
public object Asset { get; set; }
public List<JobNote> JobNotes { get; set; }
}
然后你可以反序列化它
在迭代时对 @christian-findlay 的答案进行了修改,以将JObject
类型转换为字典<字符串、对象>:
private static void RecurseDeserialize(Dictionary<string, object> result)
{
foreach (var keyValuePair in result.ToArray())
{
var jarray = keyValuePair.Value as JArray;
if (jarray != null)
{
var dictionaries = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jarray.ToString());
result[keyValuePair.Key] = dictionaries;
foreach (var dictionary in dictionaries)
{
RecurseDeserialize(dictionary);
}
}
else
{
var jobject = keyValuePair.Value as JObject;
if (jobject != null)
{
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(jobject.ToString());
result[keyValuePair.Key] = dictionary;
RecurseDeserialize(dictionary);
}
}
}
}