C# 当我没有';我事先不知道钥匙?

C# 当我没有';我事先不知道钥匙?,c#,json,json.net,C#,Json,Json.net,我有一些JSON数据如下所示: { "910719": { "id": 910719, "type": "asdf", "ref_id": 7568 }, "910721": { "id": 910721, "type": "asdf", "ref_id": 7568 }, "910723": { "id": 910723, "type": "asdf", "ref_id": 7568 } } 我如

我有一些JSON数据如下所示:

{
  "910719": {
    "id": 910719,
    "type": "asdf",
    "ref_id": 7568
  },
  "910721": {
    "id": 910721,
    "type": "asdf",
    "ref_id": 7568
  },
  "910723": {
    "id": 910723,
    "type": "asdf",
    "ref_id": 7568
  }
}
我如何使用JSON.net解析它?首先,我可以这样做:

JObject jFoo = JObject.Parse(data);
我需要能够遍历列表中的每个对象。我希望能够做到以下几点:

foreach (string ref_id in (string)jFoo["ref_id"]) {...}
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
    Console.Writeln(item.Value["ref_id"]);
}
JObject jFoo = JObject.Parse(json);

foreach (JObject obj in jFoo.Properties().Select(p => p.Value))
{
    Console.WriteLine("id: " + obj["id"]);
    Console.WriteLine("type: " + obj["type"]);
    Console.WriteLine("ref_id: " + obj["ref_id"]);
}
string[] refIds = jFoo.Properties()
                      .Select(p => (string)p.Value["ref_id"])
                      .ToArray();

Console.Write(string.Join("\r\n", refIds));


但这当然行不通。如果您在编写代码时知道关键点,那么所有示例都非常有用。如果您事先不知道密钥,它就会崩溃。

您考虑过使用JavascriptSerializer吗

您可以尝试这样做:

foreach (string ref_id in (string)jFoo["ref_id"]) {...}
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
    Console.Writeln(item.Value["ref_id"]);
}
JObject jFoo = JObject.Parse(json);

foreach (JObject obj in jFoo.Properties().Select(p => p.Value))
{
    Console.WriteLine("id: " + obj["id"]);
    Console.WriteLine("type: " + obj["type"]);
    Console.WriteLine("ref_id: " + obj["ref_id"]);
}
string[] refIds = jFoo.Properties()
                      .Select(p => (string)p.Value["ref_id"])
                      .ToArray();

Console.Write(string.Join("\r\n", refIds));
JavaScriptSerializer serializer=新的JavaScriptSerializer();
var foo=序列化程序。反序列化(数据);
foreach(foo中的变量项)
{
Console.Writeln(item.Value[“ref_id”]);
}

Konstantin的解决方案会起作用,但如果您想要一个Id列表,请执行相同的操作,而不是控制台。Writeln()使用以下命令

List<string> list = new List<string>();
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
    list.Add(item.Value["ref_id"]);
}
List List=新列表();
JavaScriptSerializer serializer=新的JavaScriptSerializer();
var foo=序列化程序。反序列化(数据);
foreach(foo中的变量项)
{
列表.添加(项.值[“ref_id”]);
}

这是可行的;这个可以用,但不雅观。我相信有更好的办法

var o = JObject.Parse(yourJsonString);

foreach (JToken child in o.Children())
{
    foreach (JToken grandChild in child)
    {
        foreach (JToken grandGrandChild in grandChild)
        {
            var property = grandGrandChild as JProperty;

            if (property != null)
            {
                Console.WriteLine(property.Name + ":" + property.Value);
            }
        }
    }
}
印刷品:

id:910719 type:asdf ref_id:7568 id:910721 type:asdf ref_id:7568 id:910723 type:asdf ref_id:7568 身份证号码:910719 类型:asdf 参考编号:7568 身份证号码:910721 类型:asdf 参考编号:7568 身份证号码:910723 类型:asdf
ref_id:7568您可以使用以下简单的LINQ查询来迭代子对象:

foreach (string ref_id in (string)jFoo["ref_id"]) {...}
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
    Console.Writeln(item.Value["ref_id"]);
}
JObject jFoo = JObject.Parse(json);

foreach (JObject obj in jFoo.Properties().Select(p => p.Value))
{
    Console.WriteLine("id: " + obj["id"]);
    Console.WriteLine("type: " + obj["type"]);
    Console.WriteLine("ref_id: " + obj["ref_id"]);
}
string[] refIds = jFoo.Properties()
                      .Select(p => (string)p.Value["ref_id"])
                      .ToArray();

Console.Write(string.Join("\r\n", refIds));
小提琴:

或者,如果您只需要所有
ref\u id
值,可以执行以下操作:

foreach (string ref_id in (string)jFoo["ref_id"]) {...}
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
    Console.Writeln(item.Value["ref_id"]);
}
JObject jFoo = JObject.Parse(json);

foreach (JObject obj in jFoo.Properties().Select(p => p.Value))
{
    Console.WriteLine("id: " + obj["id"]);
    Console.WriteLine("type: " + obj["type"]);
    Console.WriteLine("ref_id: " + obj["ref_id"]);
}
string[] refIds = jFoo.Properties()
                      .Select(p => (string)p.Value["ref_id"])
                      .ToArray();

Console.Write(string.Join("\r\n", refIds));

Fiddle:

我发现TrueWill的答案有效,但我想避免foreach,为了速度起见,尝试使用一个简单的for循环。我的结果肯定是最难看的。这里有它们,以防它们对任何人都有用。(我以书面形式离开是为了能更容易地看到事情。)

请注意,这对某些JSON不起作用,也不是完全通用的。一些空检查可以做得更好,等等

       // NOW, DOING IT ALL AS A FOR LOOP...
        // a, b, c, d - for iterator counters.
        // j1, j2, j3, j4 - the JTokens to iterator over - each is a child of the previous
        // p, q, r, s - The properties from j1/2/3/4. 

        JObject o = JObject.Parse(json);
        JToken j1 = o.First;
        for (int a = 0; a < o.Children().Count(); a++) { // Outermost loop gives us result, error, id. 
            if (j1 == null)
                continue;
            if (a > 0) {
                j1 = j1.Next;
                if (j1 == null)
                    continue;
            } 
            var p = j1 as JProperty;
            Console.WriteLine("FOR 0 = " + a.ToString() + " --- " + p.Name);
            // DO STUFF HERE.

            // FIRST INNER LOOP
            // Set up a JToken or continue
            JToken j2 = j1.Children().First() as JToken;
            if (j1.Children().Count() > 0) {
                j2 = j1.Children().First() as JToken;
            } else {
                continue;
            }
            Console.WriteLine("*** STARTING FIRST INNER...");
            for (int b = 0; b < j1.Children().Count(); b++) { // returns nothing as second loop above.
                if (j2 == null) {
                    Console.WriteLine("*** j2 null 1...");
                    continue;
                }
                if (b > 0) {
                    j2 = j2.Next;
                    if (j2 == null) {
                        Console.WriteLine("*** j2 null 2...");
                        continue;
                    }
                }
                var q = j2 as JProperty;
                // These null checks need to be != or ==, depending on what's needed. 
                if (q != null) {
                    Console.WriteLine("FOR 1 = " + a.ToString() + ","
                      + b.ToString() + " --- " + q.Name);
                    // DO STUFF HERE.
                    // ...
                } // q !null check

                // SECOND INNER LOOP
                // Set up a JToken or continue
                JToken j3;
                if (j2.Children().Count() > 0) {
                    j3 = j2.Children().First() as JToken;
                } else {
                    continue;
                }
                Console.WriteLine("****** STARTING SECOND INNER...");
                for (int c = 0; c < j2.Children().Count(); c++) {
                    if (j3 == null)
                        continue;
                    if (c > 0) {
                        j3 = j3.Next;
                        if (j3 == null)
                            continue;
                    }
                    var r = j3 as JProperty;
                    if (r == null) {
                        continue;
                    } // r null check

                    Console.WriteLine("FOR 2 = "
                        + a.ToString() + ","
                        + b.ToString() + ","
                        + c.ToString() + " --- " + r.Name);
                    // DO STUFF HERE.

                    // THIRD INNER LOOP
                    // Set up a JToken or continue
                    JToken j4;
                    if (j3.Children().Count() > 0) {
                        j4 = j3.Children().First() as JToken;
                    } else {
                        continue;
                    }

                    Console.WriteLine("********* STARTING THIRD INNER...");
                    for (int d = 0; d < j3.Children().Count(); d++) {
                        if (j4 == null)
                            continue;
                        if (c > 0) {
                            j4 = j4.Next;
                            if (j4 == null)
                                continue;
                        }
                        var s = j4 as JProperty;
                        if (s == null) {
                            continue;
                        } // s null check

                        Console.WriteLine("FOR 3 = "
                            + a.ToString() + ","
                            + b.ToString() + ","
                            + c.ToString() + ","
                            + d.ToString() + " --- " + s.Name);
                        // DO STUFF HERE.
                        // ...

                    } // for d - j3
                } // for c - j2
            } // for b - j1
        } // for a - original JObject
//现在,把这一切都当作FOR循环来做。。。
//a,b,c,d-用于迭代器计数器。
//j1、j2、j3、j4—这些JTokens到迭代器over—每个JTokens都是前一个的子项
//p、q、r、s—j1/2/3/4中的属性。
JObject o=JObject.Parse(json);
JToken j1=零。首先;
对于(inta=0;a0){
j1=j1。下一步;
如果(j1==null)
继续;
} 
var p=j1作为JProperty;
Console.WriteLine(“FOR 0=“+a.ToString()+”--“+p.Name”);
//在这里做事。
//第一内环
//设置JToken或continue
JToken j2=j1.Children().First()作为JToken;
如果(j1.Children().Count()>0){
j2=j1.Children().First()作为JToken;
}否则{
继续;
}
Console.WriteLine(“***开始第一个内部…”);
for(int b=0;b0){
j2=j2。下一步;
如果(j2==null){
Console.WriteLine(“***j2 null 2…”);
继续;
}
}
var q=j2作为j属性;
//这些空检查需要是!=或==,这取决于需要什么。
如果(q!=null){
Console.WriteLine(“FOR 1=“+a.ToString()+”,”
+b.ToString()+“--”+q.Name);
//在这里做事。
// ...
}//q!空检查
//第二内环
//设置JToken或continue
jtokenj3;
如果(j2.Children().Count()>0){
j3=j2.Children().First()作为JToken;
}否则{
继续;
}
Console.WriteLine(“*******启动第二个内部…”);
对于(int c=0;c0){
j3=j3。下一步;
如果(j3==null)
继续;
}
var r=j3,作为JProperty;
if(r==null){
继续;
}//r空检查
Console.WriteLine(“对于2=”
+a.ToString()+“,”
+b.ToString()+“,”
+c.ToString()+“--”+r.Name);
//在这里做事。
//第三内环
//设置JToken或continue
jtokenj4;
如果(j3.Children().Count()>0){
j4=j3.Children().First()作为JToken;
}否则{
继续;
}
Console.WriteLine(“*********开始第三个内部…”);
对于(int d=0;d0){
j4=j4。下一步;
if(j4==null)
继续;
}
var s=j4作为JProperty;
如果(s==null){
继续;
}//s空检查
Console.WriteLine(“对于3=”