Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Json.NET,如何将具有动态名称的对象列表解析为列表?_C#_Json_Web_Json.net - Fatal编程技术网

C# 使用Json.NET,如何将具有动态名称的对象列表解析为列表?

C# 使用Json.NET,如何将具有动态名称的对象列表解析为列表?,c#,json,web,json.net,C#,Json,Web,Json.net,下面是我从外部API接收的JSON格式示例: "object": { "property_1": { "values": { "value": 1, "displayValue": "1" } }, "property_5": { "values": { "value": 3, "displayValue": "3" } }, "property_8": { "values": {

下面是我从外部API接收的JSON格式示例:

"object": {
  "property_1": {
    "values": {
      "value": 1,
      "displayValue": "1"
    }
  },
  "property_5": {
    "values": {
      "value": 3,
      "displayValue": "3"
    }
  },
  "property_8": {
    "values": {
      "value": 1,
      "displayValue": "1"
    }
  },
  "property_14": {
    "values": {
      "value": 392,
      "displayValue": "392.0"
    }
  },
  "property_17": {
    "values": {
      "value": 14,
      "displayValue": "14"
    }
  }
}
大约有100种不同的属性类型可以发送,但它们都遵循相同的结构。唯一的区别是财产的名称(“财产1”、“财产5”等)。与其尝试编写一个包含一长串不经常使用的属性的类,不如将其解析为一个对象列表,在生成的类中使用属性名,如下所示:

public class Property
{
    public string Name { get; set; }
    public PropertyValues Values { get; set; }
}

public class PropertyValues
{
    public double Value { get; set; }
    public string DisplayValue { get; set; }
}
在这种情况下,属性名称(“属性_1”、“属性_5”等)将分配给属性对象的名称字段


如何使用Json.NET实现这一点?

还有另一种方法:您可以使用:

此外,由于
ExpandoObject
实现了
IDictionary
,因此您可以像使用字典一样使用它,并检查属性是否存在:

if(((IDictionary<string, object>)response.@object).ContainsKey("property_1"))
{

}

但这种方法需要您知道服务器将提前返回
property_14

非常通用,可以发布到任何与json相关的问题上。。。。假设在反序列化json之前,您不知道
property_14
,它甚至不起作用<代码>字符串property14Value=response.property14Value抛出异常…@EZI很抱歉,但您知道它为什么抛出异常,因为它应该是
response.object.property14value
。我要解决这个问题。@EZI解决了,顺便说一句,我觉得我得到了很多爱和恨(3次反对票),而这种方法在很多场景中都能完美地工作。而且,我希望OP能利用我的方法。我给了一个错误的动态属性访问权限,这只是一个人为错误,虽然这并没有违背我回答的目的:我给OP一个很好的提示。顺便说一句:我也想知道在测试这个答案中的代码之前/之后,谁投了+1或-1的票……如果说其他贡献者重复了你的答案,而整个答案的一部分正是我提供的方法,那就太可怕了。在其他问答中,由于其他回答者比你更成熟,通常会使用指向其他回答者的链接,说“就像在他的回答中已经说过@matias fidemraizer一样,你也可以使用动态方法”。。。事实上,我关心的是提供我认为对OP有用的好答案和建议。就我而言,我不是一个追名逐利的人,我只是回答我的观点,我不关心你是否获得100多张赞成票,甚至是反对票。嗯,我关心的是我是否获得反对票来改进我的答案。谢谢你的提醒。根据我的经验,在这种情况下,最好使用
ExpandoObject
而不是
JObject
,因为请记住,JSON.NET提供了隐式转换,将JSON值转换为简单类型,如
string
bool
int
,这可能会导致一些重载解决问题。。。顺便说一句,在其他情况下,将
动态
反序列化为
作业对象
就足够了……现在,当您再次编辑时,我理解了您和@EZI的顾虑,并展示了如何访问
“property_14”
。我发现当您使用
ExpandoObject
时,这些问题就消失了。现在OP有2到3种方法来解决相同的问题。现在我要睡觉了!晚安
long someValue = response.@object.property_1.values.value;
if(((IDictionary<string, object>)response.@object).ContainsKey("property_1"))
{

}
if(((IDictionary<string, object>)response.@object).ContainsKey("property_14"))
{
    // You've already addressed the issue, because you won't get a 
    // run-time exception since you'll access such property if it's already
    // in the returned response...
    object property_14 = response.@object.property_14;
}
var result  = JsonConvert.DeserializeObject<Root>(json);
public class Root
{
    public Dictionary<string, ValueWrapper> Object { get; set; }
}
public class ValueWrapper
{
    public PropertyValues Values { get; set; }
}

public class PropertyValues
{
    public int Value { get; set; }
    public string DisplayValue { get; set; }
}
var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring))
          .@object.property_14.values.value;

var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring))
          .@object["property_14"].values.value;