简体   繁体   English

使用C#NewtonSoft的嵌套JSON

[英]Nested JSON using c# NewtonSoft

Can anyone provide some advice, maybe with a code snippet, using C# and json.net to read some nested json? 任何人都可以使用C#和json.net提供一些建议(可能带有代码段)以读取一些嵌套json吗? My json below validates to good json using JSONLint. 我下面的json使用JSONLint验证为良好的json。 I've hit a hurdle that when parsing the json, I am unable to get into the 3rd, 4th, 6th and 8th values nested in the root. 我遇到一个障碍,当解析json时,我无法进入嵌套在根目录中的第3,第4,第6和第8值。

[{
"interactionType": "MathEditorInteraction",
"interactionId": "08506178-22ba-4fa7-a490-c785716f10dc",
"value": "blah blah blah"
},
{
"interactionType": "MathEditorInteraction",
"interactionId": "1134871f-980e-4138-9598-0d4bf480aa97",
"value": "my first value"
},
{
"interactionType": "CanvasInteraction",
"interactionId": "89cd7bec-d0e8-4111-8442-f2ab95a1410b",
"value": "my second value"
},
{
"interactionType": "FillInBlankInteraction",
"interactionId": "7e9350b4-fb85-4f12-869e-227f99f77a73",
"value": "{\"results\":[{\"id\":\"1ac6770e-2093-4b7c-b595-789be8ee6efb\",\"value\":\"my third value\"}]}"
},
{
"interactionType": "FillInBlankInteraction",
"interactionId": "6f1ca6b7-3178-44a7-b8e9-e82d8c51d1fd",
"value": "{\"results\":[{\"id\":\"b7e92fd2-9c7a-4f71-88f9-e7d43e3179b7\",\"value\":\"my fourth value\"}]}"
},
{
"interactionType": "TextBoxInteraction",
"interactionId": "284c43f9-a268-4295-b96d-bc2f6dc30f0e",
"value": "my fifth value"
},
{
"interactionType": "FillInBlankInteraction",
"interactionId": "544b9907-139a-4c78-9671-502153be2697",
"value": "{\"results\":[{\"id\":\"f4e1ba6d-61dd-4eed-9c6f-dafc2701c161\",\"value\":\"my sixth value\"}]}"
},
{
"interactionType": "TextBoxInteraction",
"interactionId": "c0a5a1f0-2cae-42fd-8726-0ad36c11f413",
"value": "my seventh value"
},
{
"interactionType": "FillInBlankInteraction",
"interactionId": "ef6a7b62-8a7b-4b7f-b876-0d78ee6c4c87",
"value": "{\"results\":[{\"id\":\"af39469e-c041-4889-9e28-61a438cf56a3\",\"value\":\"my eight value\"}]}"
},
{
"interactionType": "TextBoxInteraction",
"interactionId": "f04de5b5-8a29-4200-a886-15f7dbd575b6",
"value": "my nineth value"
}]

then some c# that I've been using: 然后我一直在使用一些C#:

JArray token = JArray.Parse(response); // response = json string above
for (int i = 0; i < token.Count; i++)
{
    String value = token[i]["value"].ToString();
}

I could be surprised with the JSON i consume...it could have n-count nested values...the purpose of my code is to get to the bottom-most child with the "value" string. 我可能会对使用的JSON感到惊讶...它可能具有n个嵌套的值...我的代码的目的是使用“值”字符串到达​​最底层的子级。 Is there a way to look at a token[i]["some string"] and see if it contains a JArray or JObject to continue parsing? 有没有办法查看令牌[i] [“某些字符串”]并查看其是否包含JArray或JObject以便继续解析?

EDIT from Timothy's suggestion, I was able to output the values. 根据蒂莫西的建议进行编辑,我能够输出这些值。 Almost there. 快好了。

static string json2 = @"[{""interactionType"": ""MathEditorInteraction"",""interactionId"": ""08506178-22ba-4fa7-a490-c785716f10dc"",""value"": ""blah blah blah""},{""interactionType"": ""MathEditorInteraction"",""interactionId"": ""1134871f-980e-4138-9598-0d4bf480aa97"",""value"": ""my first value""},{""interactionType"": ""CanvasInteraction"",""interactionId"": ""89cd7bec-d0e8-4111-8442-f2ab95a1410b"",""value"": ""my second value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""7e9350b4-fb85-4f12-869e-227f99f77a73"",""value"": ""{\""results\"":[{\""id\"":\""1ac6770e-2093-4b7c-b595-789be8ee6efb\"",\""value\"":\""my third value\""}]}""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""6f1ca6b7-3178-44a7-b8e9-e82d8c51d1fd"",""value"": ""{\""results\"":[{\""id\"":\""b7e92fd2-9c7a-4f71-88f9-e7d43e3179b7\"",\""value\"":\""my fourth value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""284c43f9-a268-4295-b96d-bc2f6dc30f0e"",""value"": ""my fifth value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""544b9907-139a-4c78-9671-502153be2697"",""value"": ""{\""results\"":[{\""id\"":\""f4e1ba6d-61dd-4eed-9c6f-dafc2701c161\"",\""value\"":\""my sixth value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""c0a5a1f0-2cae-42fd-8726-0ad36c11f413"",""value"": ""my seventh value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""ef6a7b62-8a7b-4b7f-b876-0d78ee6c4c87"",""value"": ""{\""results\"":[{\""id\"":\""af39469e-c041-4889-9e28-61a438cf56a3\"",\""value\"":\""my eight value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""f04de5b5-8a29-4200-a886-15f7dbd575b6"",""value"": ""my ninth value""}]";

var x = JsonConvert.DeserializeObject<Interaction[]>(json2);
for (int i = 0; i < x.Length; i++)
{
if (x[i].value.Contains("[{"))
    {
        var v = JsonConvert.DeserializeObject<Nested>(x[i].value);
        Console.WriteLine(v.results[0].value);
    }
else
    {
        Console.WriteLine(x[i].value);
    }       
}

Console Output: 控制台输出:

blah blah blah
my first value
my second value
my third value
my fourth value
my fifth value
my sixth value
my seventh value
my eight value
my ninth value

Still stuck on actually detecting an array deeper than the first level. 仍然停留在实际检测比第一层更深的阵列上。 You can see my hack to look for "[{" which is not preferred. 您可以看到我的技巧来寻找“ [{””,这不是首选。

EDIT: KUDOS to Jens for helping me arrive at the solution I needed today. 编辑:JENS的KUDOS帮助我找到了今天需要的解决方案。 See comments below for full explanations. 请参阅下面的评论以获取完整说明。

You can react to JToken.Type if you don't wish to go into deserializing objects. 如果您不希望反序列化对象,则可以对JToken.Type做出反应。 I actually mostly work with the JSON in a dynamic fasion in C# my self, never deserializing it into strong types, this is mostly because we work with backends where the data structures are defined by the clients and we need to be able to handle much more dynamic data. 实际上,我实际上是在自己的C#中以动态方式使用JSON,从来没有将其反序列化为强类型,这主要是因为我们使用的后端是由客户端定义数据结构的,我们需要能够处理更多的事情。动态数据。

https://dotnetfiddle.net/awUSGT https://dotnetfiddle.net/awUSGT

    dynamic arr = JArray.Parse(JSON); // response = json string above

    foreach (dynamic token in arr)
    {
        JTokenType type = ((JToken)token.value).Type;

        switch (type)
        {
            case JTokenType.String:
                Console.WriteLine(token.value);
                break;

            case JTokenType.Object:
                Console.WriteLine(token.value.results.Last.value);
                break;
        }
    }

Note that for before 8.x or 9.x (can't remember when I posted that fix) something the above will thrown an exception when casting to JToken. 请注意,对于8.x或9.x之前的版本(我记得发布此修复程序时不记得),在将其转换为JToken时,上述内容会引发异常。

So can instead do: 因此可以改为:

    dynamic arr = JArray.Parse(JSON); // response = json string above

    foreach (JObject token in arr)
    {
        dynamic value = token["value"];
        switch (token["value"].Type)
        {
            case JTokenType.String:
                Console.WriteLine(value);
                break;

            case JTokenType.Object:
                Console.WriteLine(value.results.Last.value);
                break;
        }
    }

Now as for one final note, the tool i used to prettify your JSON seemed to strip away some escaping for your values. 现在,作为最后的注释,我用来美化JSON的工具似乎剥夺了一些为您的值进行的转义。

I don't know if it was intentional that you have your embeded JSON as strings (Serialized JSON), if so you need to find a way to discover that and then parse that as well. 我不知道是否有意将JSON作为字符串(Serialized JSON)进行嵌入,如果需要,则需要找到一种方法来发现它,然后对其进行解析。

A loose/relaxed approach could be: 宽松/宽松的方法可能是:

    dynamic arr = JArray.Parse(JSON); // response = json string above

    foreach (dynamic token in arr)
    {
        string tokenvalue = (string) token.value;
        JToken value = Regex.IsMatch(tokenvalue, "^\\{.*\\}$") 
            ? JToken.Parse(tokenvalue) 
            : token.value;
        switch (value.Type)
        {
            case JTokenType.String:
                Console.WriteLine(value);
                break;

            case JTokenType.Object:
                Console.WriteLine(((dynamic)value).results.Last.value);
                break;
        }
    }

Since I don't know exactly how your "recursive nesting" looks, it is hard to guess, but something along the lines of: 由于我不完全了解您的“递归嵌套”的外观,因此很难猜测,但是有些类似的东西:

public static void Main()
{
    dynamic arr = JArray.Parse(JSON); // response = json string above

    foreach (dynamic token in arr)
    {
        JToken value = ExtractValue(token);
        Console.WriteLine(value);
    }
}

private static JToken ExtractValue(dynamic token)
{
    string tokenvalue = (string) token.value;
    JToken value = Regex.IsMatch(tokenvalue, "^\\{.*\\}$")
        ? JToken.Parse(tokenvalue)
        : token.value;

    switch (value.Type)
    {
        case JTokenType.String:
            return value;

        case JTokenType.Object:
            return ExtractValue(((dynamic) value).results.Last);

        default:
            throw new InvalidOperationException("Could not extract data, unknown json construct.");
    }
}

Maybe. 也许。

Try using this: JsonConvert.DeserializeObject<Interaction[]>(yourJson); 尝试使用此方法: JsonConvert.DeserializeObject<Interaction[]>(yourJson);

where Interaction is: Interaction在哪里:

public class Interaction
{
    public string interactionType {get;set;}
    public string interactionId {get;set;}
    public string value {get;set;}
}

Then, for the ones that have a nested JSON, you can then simply parse the value property of them as the following: 然后,对于具有嵌套JSON的对象,您可以简单地将它们的value属性解析为以下内容:

public class Nested
{
    public Result[] results {get;set;}
}

public class Result
{
    public string id {get;set;}
    public string value {get;set;}
}

Then parse it like this: 然后像这样解析它:

var v = JsonConvert.DeserializeObject<Nested>(x[8].value);

You can easily generate model classes using this service 您可以使用此服务轻松生成模型类

With this model you can easily Deserialize using Newtonsoft Json 使用此模型,您可以使用Newtonsoft Json轻松地反序列化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM