Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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元素_C#_Json - Fatal编程技术网

使用C#中不在数组中的JSON元素

使用C#中不在数组中的JSON元素,c#,json,C#,Json,我目前正在使用一个包含数组的源和一个不包含数组的源的JSON输出 带有数组的类很简单,因为我可以创建一个表示对象和对象列表的类,然后遍历列表并获取每个对象的属性。但是,在没有数组的源代码中,它将我抛出一个循环 我不知道如何反复讨论这个问题。似乎我需要为“abc”和“def”创建单独的类,即使每个类的属性都相同。有没有一个简单的方法可以做到这一点 不包含数组的示例: { "objectContainer": { "count": 25, "objects": {

我目前正在使用一个包含数组的源和一个不包含数组的源的JSON输出

带有数组的类很简单,因为我可以创建一个表示对象和对象列表的类,然后遍历列表并获取每个对象的属性。但是,在没有数组的源代码中,它将我抛出一个循环

我不知道如何反复讨论这个问题。似乎我需要为“abc”和“def”创建单独的类,即使每个类的属性都相同。有没有一个简单的方法可以做到这一点

不包含数组的示例:

    {
"objectContainer": {
    "count": 25,
    "objects": {
        "abc": {
            "name": "object1",
            "parent": "0",
            "status": "0",
        },
        "def": {
            "name": "object2",
            "parent": "0",
            "status": "0",
        }
        etc....

提前感谢您的帮助。

您可以使用继承来防止重复“abc”和“def”的属性

public class Base
{
    public string name { get; set; }
    public string parent { get; set; }
    public string status { get; set; }
}

public class Abc : Base { }

public class Def : Base { }

public class Objects
{
    public Abc abc { get; set; }
    public Def def { get; set; }
}

public class ObjectContainer
{
    public int count { get; set; }
    public Objects objects { get; set; }
}

public class RootObject
{
    public ObjectContainer objectContainer { get; set; }
}
然后使用JSON.NET可以反序列化字符串

var root = JsonConvert.DeserializeObject<RootObject>( json );
显然,在将输出写入控制台的地方,您必须检查标记类型和值,并将它们填充到对象中

更新

这很难看,但我很好奇如何将其解析为对象结构。您需要稍微更改接收对象定义

public class Base
{
    public string name { get; set; }
    public string parent { get; set; }
    public string status { get; set; }
}

public class Objects
{
    public List<Base> bases { get; set; }

    public Objects()
    {
        bases = new List<Base>();
    }
}

public class ObjectContainer
{
    public int count { get; set; }
    public Objects objects { get; set; }

    public ObjectContainer()
    {
        objects = new Objects();
    }
}

public class RootObject
{
    public ObjectContainer objectContainer { get; set; }

    public RootObject()
    {
        objectContainer = new ObjectContainer();
    }
}

这不是世界上最漂亮的代码,但只要JSON的结构不改变,不管有多少子对象或它们的名称是什么,最终都会得到一个很好的对象模型。

基于上面的JSON,您可能需要为这些对象创建类。您还可以通过继承将其中的一部分提取出来。如果可能的话,将“对象”作为一个数组会更有意义,这样您就不需要创建单独的对象。名称和实现都建议使用数组


如果无法更改JSON的结构,请查看页面底部的不同库。有些可能比其他的更有帮助。Json.NET是我通常使用的一个,您可以使用类似于JSonReader的东西获得更好的结果,这样您就不必创建过于复杂的对象结构。

您可以使用下面这样的优秀(动态)类:

// example input
var json = @"{""objectContainer"": {
""count"": 25,
""objects"": {
    ""abc"": {
        ""name"": ""object1"",
        ""parent"": ""0"",
        ""status"": ""0"",
    },
    ""def"": {
        ""name"": ""object2"",
        ""parent"": ""0"",
        ""status"": ""0"",
    }
}}";

var obj = JsonConvert.DeserializeObject(json);
var objectContainer = ((JObject)obj)["objectContainer"];
var abc = objectContainer["objects"]["abc"];
Console.WriteLine(abc["name"]);
输出为:

abc - {
"name": "object1",
"parent": "0",
"status": "0"
}
def - {
"name": "object2",
"parent": "0",
"status": "0"
}
输出1

您甚至可以直接使用加载和解析JSON代码部分(例如,如果您只能从完整的JSON字符串中提取
abc
部分):

然后可以将提取的值分配给自定义类

使用库和JObject类,您不需要用类来表示JSON。缺点是,您没有类及其属性的类型安全性


更新

您可以在不知道其名称的情况下迭代属性/对象:

var obj = JsonConvert.DeserializeObject(json);
var objectContainer = ((JObject)obj)["objectContainer"];
foreach (var o in objectContainer["objects"])
{
    if (o is JProperty)
    {
        var op = ((JProperty)o);
        Console.WriteLine("{0} - {1}", op.Name, op.Value);
    }
}
输出为:

abc - {
"name": "object1",
"parent": "0",
"status": "0"
}
def - {
"name": "object2",
"parent": "0",
"status": "0"
}

这正是我害怕的,但我喜欢减少冗余的继承解决方案!然而,由于数据可能会发生变化,因此解决方案似乎无法扩展。我不确定在数组中不使用JSON有什么好处,我对使用它还不熟悉。如果数据要更改,那么继承将不起作用。你可能也不能使用另一张海报建议的动态方法,因为你事先不知道你需要抓住什么价值。我认为对内容进行串行解析是最好的选择。至少在完成之后,您将有一个对象模型要处理。我不知道为什么制作人会这样创建JSON,这不是我会做的事情。你必须问他们为什么做出这样的选择。有趣的更新,我没有想到这一点。我不期望实际的结构会改变,所以这绝对是一个可行的解决方案。我联系了发布JSON的作者,纯粹是出于好奇,想知道为什么它是以这种方式格式化的。作为一个有效的解决办法,我将试一试。非常感谢。我不熟悉JObject.Parse,我必须研究它是否是一个可行的解决方案。我试图实现的目标是迭代每个JSON对象,而不知道每个对象的名称……例如,如果将来添加“ghi”。谢谢你提醒我!很高兴这个答案给了你新的想法。我在不知道元素名称的情况下对其进行了更新并添加了迭代。
var obj = JsonConvert.DeserializeObject(json);
var objectContainer = ((JObject)obj)["objectContainer"];
foreach (var o in objectContainer["objects"])
{
    if (o is JProperty)
    {
        var op = ((JProperty)o);
        Console.WriteLine("{0} - {1}", op.Name, op.Value);
    }
}
abc - {
"name": "object1",
"parent": "0",
"status": "0"
}
def - {
"name": "object2",
"parent": "0",
"status": "0"
}