gpt4 book ai didi

c# - 将 JSON 对象层次结构反序列化为 Dictionary 的层次结构

转载 作者:太空狗 更新时间:2023-10-30 00:42:48 37 4
gpt4 key购买 nike

我在 .NET for WinRT (C#) 中,我想将 JSON 字符串反序列化为 Dictionary<string, object> ,其中字典值稍后可以转换为实际类型。JSON 字符串可以包含一个对象层次结构,我希望在 Dictionary<string, object> 中有子对象

这是它应该能够处理的示例 JSON:

{
"Name":"John Smith",
"Age":42,
"Parent":
{
"Name":"Brian Smith",
"Age":65,
"Parent":
{
"Name":"James Smith",
"Age":87,
}
}
}

我尝试使用 DataContractJsonSerializer 这样做:

using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings();
settings.UseSimpleDictionaryFormat = true;

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<string, object>), settings);
Dictionary<string, object> results = (Dictionary<string, object>)serializer.ReadObject(ms);
}

这实际上在第一层工作得很好,但是 “Parent” 只是一个不能转换为 Dictionary<string, object> 的对象:

Dictionary<string, object> parent = (Dictionary<string, object>)results["Parent"];
Cannot cast 'results["Parent"]' (which has an actual type of 'object') to 'System.Collections.Generic.Dictionary<string,object>'

然后我尝试使用 Json.NET 但子对象是 JObject 本身是 IDictionary<string, JToken> ,这迫使我遍历整个层次结构并再次转换它们。

有人知道如何使用现有的序列化器解决这个问题吗?

编辑

我正在使用 Dictionary<string, object>因为我的对象因一个服务器调用而异(例如,“Id” 属性可能是 “id”、*“cust_id”* 或 “customerId” 取决于请求)并且因为我的应用不是唯一使用这些服务的应用,所以我不能改变它,至少现在是这样。

因此,我发现在这种情况下使用DataContractAttributeDataMemberAttribute 很不方便。相反,我想将所有内容存储在通用字典中,并有一个强类型属性“Id”,它在字典中查找“id”、“cust_id”或“customerId”,使其对 UI 透明。

这个系统与 JSON.NET 配合得很好,但是如果服务器返回一个对象层次结构,子对象将作为 JObjects 存储在我的字典而不是另一个字典中。

总而言之,我正在寻找一个有效的系统来将对象层次结构转换为 Dictionary<string, object> 的层次结构使用 WinRT 中可用的 JSON 序列化器。

最佳答案

我正在使用 JSON.NET 库和 ExpandoObject 类的组合解决 WinRT 应用程序中的同一问题。该库能够很好地将 JSON 数据反序列化为实现 IDictionary 的 ExpandoObjects。 ExpandoObject 的键值对的值很容易被视为另一个 ExpandoObject。

这是我使用的方法,适用于您的样本:

void LoadJSONData()
{
string testData = "{ \"Name\":\"John Smith\", \"Age\":42, \"Parent\": { \"Name\":\"Brian Smith\", \"Age\":65, \"Parent\": { \"Name\":\"James Smith\", \"Age\":87, } } }";

ExpandoObject dataObj = JsonConvert.DeserializeObject<ExpandoObject>(testData, new ExpandoObjectConverter());

// Grab the parent object directly (if it exists) and treat as ExpandoObject
var parentElement = dataObj.Where(el => el.Key == "Parent").FirstOrDefault();
if (parentElement.Value != null && parentElement.Value is ExpandoObject)
{
ExpandoObject parentObj = (ExpandoObject)parentElement.Value;
// do something with the parent object...
}

// Alternately, iterate through the properties of the expando
foreach (var property in (IDictionary<String, Object>)dataObj)
{
if (property.Key == "Parent" && property.Value != null && property.Value is ExpandoObject)
{
foreach (var parentProp in (ExpandoObject)property.Value)
{
// do something with the properties in the parent expando
}
}
}
}

关于c# - 将 JSON 对象层次结构反序列化为 Dictionary<string, object> 的层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13631208/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com