Move property child object to root

久未见 提交于 2021-01-28 06:08:05

问题


I have a c# object that natively serializes to

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

and I want it to be

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

where all the properties within LrsFeature are added to the root level.

My attempt

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

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

This gives me

{
  "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",
}

I then need to delete the LrsFeature object, but it seems a little bit hacky. I figured JSON.NET might have a more direct method of doing this


回答1:


You can do what you want like this:

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

Fiddle: https://dotnetfiddle.net/zsOQFE




回答2:


What you're looking to do is deserialize a JSON string and then deep-flatten it. You can do this using the recursive method:

Code

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

}

Usage

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


来源:https://stackoverflow.com/questions/43898650/move-property-child-object-to-root

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!