【问题标题】:C# Decoding JSON - All Objects are the same with a unique nameC# 解码 JSON - 所有对象都具有唯一名称
【发布时间】:2016-02-06 01:16:21
【问题描述】:

有人对 System.Runtime.Serialization.Json 和 DataContracts 有任何经验吗?我有一个要转换为 C# 的 Perl 脚本,但我似乎无法弄清楚如何制作这个 DataContract 来解释来自网站的响应是一堆对象的事实。我试图假装这些对象不存在,并且我试图定义一个合同,指定出现的第一个对象字符串,但我无法让它解析任何单独的数据位。这是作为请求响应返回的 200 个对象中的 2 个的示例。

当前的数据合同尝试:

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(JsonMachines));
JsonMachines machines = (JsonMachines)ser.ReadObject(resp.GetResponseStream());

[DataContract]
class JsonMachines
{
    [DataMember]
    public JsonMachine dc54806f4fe34cf5a83b0676555f8658;

}
[DataContract]
class JsonMachine
{
    [DataMember]
    public string guid;
    [DataMember]
    public int lost_contact;
    [DataMember]
    public string org;
    [DataMember]
    public string timezone;
}

来自服务器的 JSON 响应:

{
   "dc54806f4fe34cf5a83b0676555f8658" : {
      "shadowprotect" : {
         "jobs" : [],
         "version" : {
            "is_expired" : false,
            "is_running" : true,
            "lang" : "en",
            "is_installed" : true,
            "version" : "6.0.8",
            "is_trial" : false,
            "name" : "ShadowProtect SPX",
            "is_msp" : false,
            "company" : ""
         }
      },
      "lost_contact" : 0,
      "org" : "site : name",
      "timezone" : -18000,
      "status" : "ok",
      "name" : "MACHINENAME2",
      "tags" : [],
      "machine_details" : {
         "last_boot" : "2016-01-21T10:54:11.557000",
         "volumes" : [
            {
               "mountpoint" : "C:\\",
               "device" : "\\\\?\\Volume{07897f98-6618-11e5-8055-806e6f6e6963}\\",
               "size" : 305242,
               "boot" : false,
               "readonly" : false,
               "removable" : false,
               "os_vol" : true,
               "used" : 57787,
               "label" : ""
            },
            {
               "mountpoint" : null,
               "device" : "\\\\?\\Volume{07897f99-6618-11e5-8055-806e6f6e6963}\\",
               "size" : 99,
               "boot" : false,
               "readonly" : false,
               "removable" : false,
               "os_vol" : false,
               "used" : 28,
               "label" : "System Reserved"
            }
         ],
         "ram" : 3945
      },
      "imagemanager" : {
         "folders" : []
      }
   },
   "c947116fc62c40c2932e850944f78550" : {
      "shadowprotect" : {
         "jobs" : [],
         "version" : {
            "is_expired" : true,
            "is_running" : true,
            "days_to_expire" : 0,
            "lang" : "en",
            "is_installed" : true,
            "version" : "4.2.7.19756",
            "name" : "ShadowProtect",
            "is_msp" : true,
            "company" : null
         }
      },
      "lost_contact" : 0,
      "org" : "site : name2",
      "timezone" : -18000,
      "status" : "ok",
      "name" : "MACHINENAME",
      "tags" : [],
      "machine_details" : {
         "last_boot" : "2016-01-28T08:34:54.486000",
         "volumes" : [
            {
               "mountpoint" : "C:\\",
               "device" : "\\\\?\\Volume{bcbc546f-291f-11e2-9a3f-806e6f6e6963}\\",
               "size" : 476153,
               "boot" : false,
               "readonly" : false,
               "removable" : false,
               "os_vol" : true,
               "used" : 145434,
               "label" : "OS"
            },
            {
               "mountpoint" : null,
               "device" : "\\\\?\\Volume{bcbc546e-291f-11e2-9a3f-806e6f6e6963}\\",
               "size" : 745,
               "boot" : false,
               "readonly" : false,
               "removable" : false,
               "os_vol" : false,
               "used" : 224,
               "label" : "RECOVERY"
            }
         ],
         "ram" : 4052
      },
      "imagemanager" : {
         "folders" : []
      }
   }
}

【问题讨论】:

    标签: c# json


    【解决方案1】:

    您将 JsonMachine.timezone 定义为字符串可能会有所不同,但在您的 JSON 中它是以整数形式出现的。

    另外,请记住,DataContractSerializer 依赖于顺序。据我所知,它应该选择“org”和“timezone”。因为你没有使用[DataMember(Order = 1)] 它按字母顺序查找。

    dc54806f4fe34cf5a83b0676555f8658 对象上没有“guid”属性或“lost_contact”属性,因此它首先要查找“org”。一旦找到它,它就不会在以后的查找中查看以前的属性。估计是性能提升。

    您可以使用上述属性自行设置特定的订单期望。但是顺序必须保持一致,因为如果对象杂乱无章,DataContractSerializer 就会出现问题,并且可能不得不转移到 Newtonsoft.Json,这是一个不错的库。

    【讨论】:

    • 感谢您对这个 jeromeyers 的洞察,这是我什至不知道我必须看的东西。来自 Perl,它将所有内容放入一个哈希中,我可以随意查询一些位。我采用了迈克尔提出的一些代码,但它并没有解决我遇到的第一个问题,即无法读取对象。您会注意到他将类标记为第一个对象的名称,但由于每个对象之间的名称都不同,我不知道如何解释它。
    【解决方案2】:

    【讨论】:

    • 所以没有任何错误。 JsonMachines 机器对象总是返回 null。我看到您定义了一个公共类 Dc54806f4fe34cf5a83b0676555f8658 这只是其中一个字符串,是否适用于响应 c947116fc62c40c2932e850944f78550 中的下一个,或者我是否必须为每个字符串(对象)重新定义公共类 200 次,然后如果一个新的被添加到列表中它不会序列化,因为我没有一个类?另外,我修改了代码来测试这个,序列化对象(机器)仍然返回为空。
    • 好的,现在我看到了这个问题。我以前没有越过这个,这是一个非常奇怪的反应,对象得到了不同的名字,但在孩子方面却是一样的。我想说你想输入 RootName 找到这个,我希望它有帮助 stackoverflow.com/questions/23648193/…
    猜你喜欢
    • 2011-10-19
    • 2023-03-23
    • 2016-04-14
    • 1970-01-01
    • 2014-09-23
    • 2017-09-13
    • 2023-03-25
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多