使用c#NewtonSoft嵌套JSON



有人能用C#和json.net读取一些嵌套的json提供一些建议吗?下面的json使用JSONLint验证为良好的json。我遇到了一个障碍,在解析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"
}]

然后我一直在使用的一些c#:

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

我可能会对我使用的JSON感到惊讶。。。它可以有n个嵌套值。。。我的代码的目的是用"value"字符串找到最底层的子项。有没有一种方法可以查看令牌[i]["some string"],并查看它是否包含JArray或JObject以继续解析?

根据Timothy的建议编辑,我能够输出这些值。差不多到了。

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);
    }       
}

控制台输出:

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

仍然坚持实际检测到比第一层更深的阵列。你可以看到我的破解来寻找"〔{〕",这不是首选。

编辑:感谢Jens帮助我找到了今天需要的解决方案。请参阅下面的评论以获得完整的解释。

您可以对JToken做出反应。如果不希望反序列化对象,请键入。事实上,我自己在C#中主要以动态方式处理JSON,从未将其反序列化为强类型,这主要是因为我们使用后台,其中数据结构由客户端定义,我们需要能够处理更多的动态数据。

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;
        }
    }

请注意,对于8.x或9.x之前的版本(不记得我是什么时候发布该修复程序的),上面的内容在转换为JToken时会引发异常。

所以可以改为:

    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;
        }
    }

最后一点,我用来美化JSON的工具似乎去掉了一些值的转义。

我不知道你是否有意将嵌入的JSON作为字符串(序列化JSON),如果是这样,你需要找到一种方法来发现它,然后解析它。

宽松/放松的方法可以是:

    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;
        }
    }

由于我不知道你的"递归嵌套"是什么样子的,所以很难猜测,但大致如下:

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.");
    }
}

也许吧。

您可以使用此服务轻松生成模型类

使用此模型,您可以使用Newtonsoft Json 轻松进行反序列化

尝试使用此:JsonConvert.DeserializeObject<Interaction[]>(yourJson);

其中Interaction为:

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

然后,对于具有嵌套JSON的那些,您可以简单地将它们的value属性解析如下:

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

然后像这样解析:

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

相关内容

  • 没有找到相关文章

最新更新