将属性子对象移动到root

时间:2017-05-10 16:58:54

标签: c# json json.net

我有一个c#对象,原生序列化为

{
  "LrsFeature": {
    "MEASURE": 1.233242,
    "STATION_ID": "brians station",
    "NLF_ID": "brians route"
  },
  "EVENT_ID": "00000000-0000-0000-0000-000000000000",
}

我希望它是

{
  "MEASURE": 1.233242,
  "STATION_ID": "brians station",
  "NLF_ID": "brians route",
  "EVENT_ID": "00000000-0000-0000-0000-000000000000",
}

其中LrsFeature中的所有属性都添加到根级别。

我的尝试

            var events = JObject.FromObject(LrsEvent);
            var attrs = JObject.FromObject(LrsEvent.LrsFeature);

            events.Merge(attrs, new JsonMergeSettings
            {
                MergeArrayHandling = MergeArrayHandling.Union
            });

这给了我

{
  "MEASURE": 1.233242,
  "STATION_ID": "brians station",
  "NLF_ID": "brians route",
  "LrsFeature": {
    "MEASURE": 1.233242,
    "STATION_ID": "brians station",
    "NLF_ID": "brians route"
  },
  "EVENT_ID": "00000000-0000-0000-0000-000000000000",
}

然后我需要删除LrsFeature对象,但它似乎有点hacky。我认为JSON.NET可能有更直接的方法来做到这一点

3 个答案:

答案 0 :(得分:2)

你可以这样做你想做的事:

    JObject jo = JObject.FromObject(LrsEvent);
    JProperty lrs = jo.Property("LrsFeature");
    jo.Add(lrs.Value.Children<JProperty>());
    lrs.Remove();
    string json = jo.ToString();

小提琴:https://dotnetfiddle.net/zsOQFE

答案 1 :(得分:1)

您要做的是反序列化JSON字符串,然后对其进行深度展平。您可以使用递归方法执行此操作:

<强>代码

public class JsonExtensions
{
    /// <summary>
    /// Deeply flattens a json object to a dictionary.
    /// </summary>
    /// <param name="jsonStr">The json string.</param>
    /// <returns>The flattened json in dictionary kvp.</returns>
    public static Dictionary<string, object> DeepFlatten(string jsonStr)
    {
        var dict = new Dictionary<string, object>();
        var token = JToken.Parse(jsonStr);
        FillDictionaryFromJToken(dict, token, String.Empty);
        return dict;
    }

    private static void FillDictionaryFromJToken(Dictionary<string, object> dict, JToken token, string prefix)
    {
        if(token.Type == JTokenType.Object)
        {
            foreach (var property in token.Children<JProperty>())
            {
                FillDictionaryFromJToken(dict, property.Value, property.Name);
                // Uncomment and replace if you'd like prefixed index
                // FillDictionaryFromJToken(dict, value, Prefix(prefix, property.Name));
            }
        }
        else if(token.Type == JTokenType.Array)
        {
            var idx = 0;
            foreach (var value in token.Children())
            {
                FillDictionaryFromJToken(dict, value, String.Empty);
                idx++;
                // Uncomment and replace if you'd like prefixed index
                // FillDictionaryFromJToken(dict, value, Prefix(prefix, idx.ToString()));
            }
        }
        else // The base case
        {
            dict[prefix] = ((JValue)token).Value; // WARNING: will ignore duplicate keys if you don't use prefixing!!!
        }
    }

    private static string Prefix(string prefix, string tokenName)
    {
        return String.IsNullOrEmpty(prefix) ? tokenName : $"{prefix}.{tokenName}";
    }

}

<强>用法

var jsonStr = "{\"LrsFeature\":{\"MEASURE\":1.233242,\"STATION_ID\":\"brians station\",\"NLF_ID\":\"brians route\"},\"EVENT_ID\":\"00000000-0000-0000-0000-000000000000\"}";
var dict = JsonExtensions.DeepFlatten(jsonStr);

foreach (var kvp in dict)
    Console.WriteLine($"{kvp.Key}={kvp.Value}");

答案 2 :(得分:0)

处理简单情况的扩展方法:

public static JProperty MoveToParent(this JProperty property)
{
    if (property is { Parent: JObject { Parent: JProperty { Parent: JObject parent } } })
    {
        property.Remove();
        parent.Add(property);
        return property;
    }

    throw new InvalidOperationException("Could not move to parent.");
}