当前位置: 首页 > 面试题库 >

将JSON对象层次结构反序列化为Dictionary层次结构

施赞
2023-03-14
问题内容

我在 .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);
}

实际上,这对于第一个级别是可行的,但是 “父母” 只是一个不能强制转换为的对象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数据很好地反序列化为ExpandoObjects,后者实现IDictionary。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
            }
        }
    }
}


 类似资料:
  • 零售商店的正确模式是什么?公司从商店销售产品。 这似乎违反了我对OOP所知的全部知识。通过层次结构向下传递数据的方法--在对象之间复制参数?我错过了什么?

  • 我想枢轴的数据帧像: 进入具有如下分层列的数据帧: 我尝试了,但它只会给我一个这样的框架: 如何更改列的层次结构?

  • 现在我和杰克逊一起工作,我有一些问题。 首先。我有两个服务,第一个是数据收集和发送服务,第二个是接收这些数据,例如,将其记录到文件中。 因此,第一个服务具有如下类层次结构: 第二个服务具有如下类层次结构: 第一个服务对无所知。 我在第一个服务上发送数据的方式: 所以,我想将json拟人化为的Collection,而不是的Collection(

  • 5.4.1 层次化体系结构 层次化设计是构造复杂系统的一个基本方法,按此方法设计出的系统具有层次化体系结构。现实世界中这种层次化结构俯拾皆是。例如,一幢高楼总是从最底层打基础开始,一层 一层地加高。又如,我国的行政组织具有街道、区、市、省、中央这样的层次化结构。 计算机软件的各个构件也经常组织成这样的层次体系结构。在层次体系中,下层构件为 上层构件提供服务,上层构件使用下层构件的服务,上层和下层之

  • 问题内容: 在“深度”对象层次结构中使用Builder模式的最佳实践是什么?详细地说,我探讨了将Joshua Bloch提出的Builder模式应用于我的XML绑定代码的想法(我使用的是SimpleXML,但是这个问题将适用于任何情况)。我的对象层次结构深达4个级别,具有不同程度的复杂性。我的意思是,在某些级别上,我的对象只有几个属性,而在其他级别上,我最多可以有10个属性。 因此,请考虑以下假设

  • 本规范定义了一个用于部署和打包用途的,可存在于开放文件系统、归档文件或一些其他形式中的层次结构。建议 servlet 容器支持这种结构作为运行时表示形式,但不是必须的.