Deserializing a JSON object hierarchy into a hierarchy of Dictionarylt;string, objectgt;(将 JSON 对象层次结构反序列化为 Dictionarylt;string, objectgt; 的层次结构)
问题描述
我在 .NET for WinRT (C#) 中,我想将 JSON 字符串反序列化为 Dictionary
Dictionary<string, object> 中有子对象.
I'm in .NET for WinRT (C#) and I'd like to deserialize a JSON string to a Dictionary<string, object>
, where the dictionary value can later be converted to the actual type.
The JSON string can contain an object hierarchy and I'd like to have child objects in Dictionary<string, object>
as well.
这是它应该能够处理的示例 JSON:
Here's a sample JSON it should be able to handle:
{
"Name":"John Smith",
"Age":42,
"Parent":
{
"Name":"Brian Smith",
"Age":65,
"Parent":
{
"Name":"James Smith",
"Age":87,
}
}
}
我尝试使用 DataContractJsonSerializer 这样做:
I tried with the DataContractJsonSerializer doing as so:
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
的对象::p>
This actually works fine for the first level, but then "Parent" is just an object which cannot be casted to a 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
,这迫使我遍历整个层次结构并转换它们重新来过.
I then tried using Json.NET but child objects are JObject themselves being IDictionary<string, JToken>
, which forces me to iterate through the full hierarchy and convert them over again.
有人知道如何使用现有的序列化程序解决这个问题吗?
Would someone know how to solve this problem using an existing serializer?
编辑
我使用 Dictionary<string, object>
因为我的对象因一个服务器调用而异(例如,"Id" 属性可能是 "id"、*"cust_id"* 或 "customerId" 取决于请求)并且由于我的应用程序不是唯一使用这些服务的应用程序,我无法更改它,在至少现在.
I'm using Dictionary<string, object>
because my objects vary from one server call to another (e.g. the "Id" property might be "id", *"cust_id"* or "customerId" depending on the request) and as my app isn't the only app using those services, I can't change that, at least for now.
因此,我发现在这种情况下使用 DataContractAttribute 和 DataMemberAttribute 很不方便.相反,我想将所有内容存储在通用字典中,并有一个强类型属性Id",它在字典中查找id"、cust_id"或customerId",使其对 UI 透明.
Therefore, I found it inconvenient to use DataContractAttribute and DataMemberAttribute in this situation. Instead I'd like to store everything in a generic dictionary, and have a single strongly-typed property "Id" which looks for "id", "cust_id" or "customerId" in the dictionary making it transparent for the UI.
这个系统与 JSON.NET 配合得很好,但是如果服务器返回一个对象层次结构,子对象将作为 JObjects 存储在我的字典中,而不是另一个字典中.
This system works great with JSON.NET, however if ever the server returns an object hierarchy, sub-objects will be stored as JObjects in my dictionary instead of another dictionary.
总而言之,我正在寻找一个有效的系统来使用 WinRT 中可用的 JSON 序列化程序将对象层次结构转换为 Dictionary
的层次结构.
To sum-up, I'm looking for an efficient system to transform an object hierarchy into a hierarchy of Dictionary<string, object>
using a JSON serializer available in WinRT.
推荐答案
我正在使用 JSON.NET 库和 ExpandoObject 类的组合在 WinRT 应用程序中解决同样的问题.该库能够很好地将 JSON 数据反序列化为实现 IDictionary 的 ExpandoObjects.ExpandoObject 的键值对的值很容易被视为另一个 ExpandoObject.
I'm addressing this same issue in a WinRT app using a combination of the JSON.NET library and the ExpandoObject class. The library is able to deserialize JSON data quite nicely into ExpandoObjects, which implement IDictionary. The value of an ExpandoObject's key-value pair may easily be treated as another ExpandoObject.
这是我使用的方法,适用于您的示例:
Here's the approach I used, adapted to your sample:
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
}
}
}
}
这篇关于将 JSON 对象层次结构反序列化为 Dictionary<string, object> 的层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将 JSON 对象层次结构反序列化为 Dictionary<string, object> 的层次结构
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 输入按键事件处理程序 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01