问题
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