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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/279.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# 把一个JToken弄平_C#_Json_Json.net - Fatal编程技术网

C# 把一个JToken弄平

C# 把一个JToken弄平,c#,json,json.net,C#,Json,Json.net,假设我有以下JToken: @"{ ""data"": [ { ""company"": { ""ID"": ""12345"", ""location"": ""Some Location"" }, ""name"": ""Some Name"" } ] }"; 我想将此令牌传递到一个FlattToken函数中

假设我有以下JToken:

@"{
    ""data"": [
        {
            ""company"": {
                ""ID"": ""12345"",
                ""location"": ""Some Location""
            },
            ""name"": ""Some Name""
        }
    ]
}";
我想将此令牌传递到一个FlattToken函数中,该函数输出此JToken:

@"{
    ""data"": [
        {
            ""company_ID"": ""12345"",
            ""company_location"": ""Some Location"",
            ""name"": ""Some Name""
        }
]}"
这样做的原因是,这样我就可以获取平坦的JToken并将其反序列化到数据表中

不过,我在一堆工作项目、JTokens、jproperty和其他JMadness中迷失了方向。我看到了答案,这是有帮助的,但我仍然没有得到正确的答案

以下是我目前掌握的情况:

public static JToken FlattenToken(JToken token)
{
    foreach (JToken topLevelItem in token["data"].Children())
    {
        foreach (JToken field in topLevelItem.Value<JToken>())
        {
            foreach (JProperty property in field.Value<JObject>().Properties())
            {
                field.AddAfterSelf(JObject.Parse(@"{""" + property.Name + "_" + property.Value));
            }

            field.Remove();
        }
    }

    return token;
}
以及通过第二个foreach循环的第一次迭代,字段=

"company": {
    "ID": "12345"
}
到目前为止看起来不错。但是当我点击最里面的foreach循环时,我在foreach行上得到一个异常:“无法将Newtonsoft.Json.Linq.JProperty强制转换为Newtonsoft.Json.Linq.JToken。”

不知道那里发生了什么。我的印象是field.Value调用将生成一个JToken并尝试将其转换为一个JProperty。那么,正如错误所暗示的那样,JProperty在哪里试图被铸造成JToken呢


而且,这感觉像是一种相当粗俗的方式来平复JToken。有更好的方法吗?

Json.NET中对象的层次结构可能相当深。可以在中找到粗略的指南

要解决此问题,首先需要一个扩展方法来获取
JObject
的属性,然后在带有名称前缀的集合中返回:

public static class JsonExtensions
{
    public static IEnumerable<KeyValuePair<string, JToken>> FlattenFields(this JObject obj, string prefix)
    {
        foreach (var field in obj)
        {
            string fieldName = prefix + "_" + field.Key;
            var fieldValue = field.Value;
            yield return new KeyValuePair<string, JToken>(fieldName, fieldValue);
        }
    }
}
最后,将它们放在一起创建一个方法,该方法将命名的
JObject
属性提升到其父属性
JObject
,并在属性名称前加下划线:

public static class JsonExtensions
{
    public static JToken PromoteNamedPropertiesToParents(this JToken token, string propertyName)
    {
        return token.EditFields(pair =>
        {
            if (pair.Key == propertyName && pair.Value is JObject)
            {
                return ((JObject)pair.Value).FlattenFields(pair.Key);
            }
            return pair.Yield();
        });
    }
}
然后,为了测试:

public static class TestFlatten
{
    public static void Test()
    {
        string jsonString = @"{
            ""data"": [
                {
                    ""company"": {
                        ""ID"": ""12345"",
                        ""location"": ""Some Location""
                    },
                    ""name"": ""Some Name""
                }
            ]
        }";
        JObject obj = JObject.Parse(jsonString);
        var newObj = (JObject)obj.PromoteNamedPropertiesToParents("company");
        Debug.WriteLine(newObj);
    }
}
输出为:

{
  "data": [
    {
      "company_ID": "12345",
      "company_location": "Some Location",
      "name": "Some Name"
    }
  ]
}

这就是你想要的。请注意,此代码创建了一个新的
JObject
层次结构,而不是修改原始层次结构。

这太棒了。非常有帮助!
public static class TestFlatten
{
    public static void Test()
    {
        string jsonString = @"{
            ""data"": [
                {
                    ""company"": {
                        ""ID"": ""12345"",
                        ""location"": ""Some Location""
                    },
                    ""name"": ""Some Name""
                }
            ]
        }";
        JObject obj = JObject.Parse(jsonString);
        var newObj = (JObject)obj.PromoteNamedPropertiesToParents("company");
        Debug.WriteLine(newObj);
    }
}
{
  "data": [
    {
      "company_ID": "12345",
      "company_location": "Some Location",
      "name": "Some Name"
    }
  ]
}