Suppose I have the following JToken:
#"{
""data"": [
{
""company"": {
""ID"": ""12345"",
""location"": ""Some Location""
},
""name"": ""Some Name""
}
]
}";
I want to pass this token into a FlattenToken function that outputs this JToken:
#"{
""data"": [
{
""company_ID"": ""12345"",
""company_location"": ""Some Location"",
""name"": ""Some Name""
}
]}"
The reason for doing this is so that I can then take the flattened JToken and deserialize it into a DataTable.
I'm getting lost in a jumble of JObjects, JTokens, JProperties, and other JMadness, though. I saw the answer on this post, which was helpful, but I'm still not getting it right.
Here's what I have so far:
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;
}
The first iteration through the outer foreach loop, topLevelItem =
{
"company": {
"ID": "12345"
},
"name": "Some Name"
}
And the first iteration through the second foreach loop, field =
"company": {
"ID": "12345"
}
Looking good so far. But when I hit the innermost foreach loop, I get an exception on the foreach line: "Cannot cast Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JToken."
Not sure what's going on there. I was under the impression that the field.Value call was going to produce a JToken and try to cast it to a JProperty. So where is a JProperty trying to be casted to a JToken, as the error suggests?
Also, this feels like a pretty gross way of flattening out a JToken. Is there a better way?
The hierarchy of objects in Json.NET can be rather deep. A rough guide can be found in this answer.
To solve your problem, you first need an extension method to take the properties of a JObject and return then in a collection with a name prefix:
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);
}
}
}
Next, you need some recursive tools to iterate through a Json.NET hierarchy and rewrite the collection of properties of selected JObject's:
public static class JsonExtensions
{
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
public static JToken EditFields(this JToken token, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
if (token == null)
return null;
switch (token.Type)
{
case JTokenType.Array:
return EditFields((JArray)token, editor);
case JTokenType.Object:
return EditFields((JObject)token, editor);
default:
return token;
}
}
static JToken EditFields(JArray array, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
JArray newArray = null;
foreach (var element in array)
{
var newElement = EditFields(element, editor);
if (newElement != null)
{
if (newArray == null)
newArray = new JArray();
newArray.Add(newElement);
}
}
return newArray;
}
static JToken EditFields(JObject obj, Func<KeyValuePair<string, JToken>, IEnumerable<KeyValuePair<string, JToken>>> editor)
{
JObject newObj = null;
foreach (var field in obj)
{
foreach (var newField in editor(field))
{
if (newObj == null)
newObj = new JObject();
newObj[newField.Key] = newField.Value.EditFields(editor);
}
}
return newObj;
}
}
Finally, put these together to create a method that promotes properties of a named JObject property to their parent JObject, prepending the property name plus an underscore:
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();
});
}
}
And then, to test:
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);
}
}
And the output is:
{
"data": [
{
"company_ID": "12345",
"company_location": "Some Location",
"name": "Some Name"
}
]
}
Which is what you want. Please note that this code creates a new JObject hierarchy rather than modifying the original hierarchy.
Related
I am working with System.Text.Json in my project as I am processing large files so also decided to use it for processing GraphQL responses.
Due to the nature of GraphQL sometimes I get highly nested responses that are not fixed and don't make sense to map to a class. I usually need to check a few properties on the response.
My issue is with JsonElement. To check nested properties feels very clumsy and I feel like there should be a better way to approach this.
For example take my below code simulating a response I get. I just want to check if 2 properties exist (id & originalSrc) and if they do get their value but it feels like I have made a meal of the code. Is there a better/clearer/more succinct way to write this?
var raw = #"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
}
]
}
}
}";
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
JsonElement node = new JsonElement();
string productIdString = null;
if (doc.TryGetProperty("data", out var data))
if (data.TryGetProperty("products", out var products))
if (products.TryGetProperty("edges", out var edges))
if (edges.EnumerateArray().FirstOrDefault().ValueKind != JsonValueKind.Undefined && edges.EnumerateArray().First().TryGetProperty("node", out node))
if (node.TryGetProperty("id", out var productId))
productIdString = productId.GetString();
string originalSrcString = null;
if(node.ValueKind != JsonValueKind.Undefined && node.TryGetProperty("featuredImage", out var featuredImage))
if (featuredImage.TryGetProperty("originalSrc", out var originalSrc))
originalSrcString = originalSrc.GetString();
if (!string.IsNullOrEmpty(productIdString))
{
//do stuff
}
if (!string.IsNullOrEmpty(originalSrcString))
{
//do stuff
}
It is not a crazy amount of code but checking a handful of properties is so common I would like a cleaner more readble approach.
You could add a couple of extension methods that access a child JsonElement value by property name or array index, returning a nullable value if not found:
public static partial class JsonExtensions
{
public static JsonElement? Get(this JsonElement element, string name) =>
element.ValueKind != JsonValueKind.Null && element.ValueKind != JsonValueKind.Undefined && element.TryGetProperty(name, out var value)
? value : (JsonElement?)null;
public static JsonElement? Get(this JsonElement element, int index)
{
if (element.ValueKind == JsonValueKind.Null || element.ValueKind == JsonValueKind.Undefined)
return null;
// Throw if index < 0
return index < element.GetArrayLength() ? element[index] : null;
}
}
Now calls to access nested values can be chained together using the null-conditional operator ?.:
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
var node = doc.Get("data")?.Get("products")?.Get("edges")?.Get(0)?.Get("node");
var productIdString = node?.Get("id")?.GetString();
var originalSrcString = node?.Get("featuredImage")?.Get("originalSrc")?.GetString();
Int64? someIntegerValue = node?.Get("Size")?.GetInt64(); // You could use "var" here also, I used Int64? to make the inferred type explicit.
Notes:
The extension methods above will throw an exception if the incoming element is not of the expected type (object or array or null/missing). You could loosen the checks on ValueKind if you never want an exception on an unexpected value type.
There is an open API enhancement request Add JsonPath support to JsonDocument/JsonElement #31068. Querying via JSONPath, if implemented, would make this sort of thing easier.
If you are porting code from Newtonsoft, be aware that JObject returns null for a missing property, while JArray throws on an index out of bounds. Thus you might want to use the JElement array indexer directly when trying to emulate Newtonsoft's behavior, like so, since it also throws on an index out of bounds:
var node = doc.Get("data")?.Get("products")?.Get("edges")?[0].Get("node");
Demo fiddle here.
To make my code a little more readable I created a method that uses a dot-separated path with System.Text.Json similar to a path parameter for the SelectToken() method in Newtonsoft.Json.
JsonElement jsonElement = GetJsonElement(doc, "data.products.edges");
I then use jsonElement.ValueKind to check the return type.
private static JsonElement GetJsonElement(JsonElement jsonElement, string path)
{
if (jsonElement.ValueKind == JsonValueKind.Null ||
jsonElement.ValueKind == JsonValueKind.Undefined)
{
return default;
}
string[] segments =
path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
for (int n = 0; n < segments.Length; n++)
{
jsonElement = jsonElement.TryGetProperty(segments[n], out JsonElement value) ? value : default;
if (jsonElement.ValueKind == JsonValueKind.Null ||
jsonElement.ValueKind == JsonValueKind.Undefined)
{
return default;
}
}
return jsonElement;
}
I created another simple method to retrieve the value of the returned JsonElement as a string.
private static string GetJsonElementValue(JsonElement jsonElement)
{
return
jsonElement.ValueKind != JsonValueKind.Null &&
jsonElement.ValueKind != JsonValueKind.Undefined ?
jsonElement.ToString() :
default;
}
Below are two functions applied to the OP's sample:
public void Test()
{
string raw = #"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
}
]
}
}
}";
JsonElement doc = JsonSerializer.Deserialize<JsonElement>(raw);
JsonElement jsonElementEdges = GetJsonElement(doc, "data.products.edges");
string originalSrcString = default;
string originalIdString = default;
if (jsonElementEdges.ValueKind == JsonValueKind.Array)
{
int index = 0; // Get the first element in the 'edges' array
JsonElement edgesFirstElem =
jsonElementEdges.EnumerateArray().ElementAtOrDefault(index);
JsonElement jsonElement =
GetJsonElement(edgesFirstElem, "node.featuredImage.originalSrc");
originalSrcString = GetJsonElementValue(jsonElement);
jsonElement =
GetJsonElement(edgesFirstElem, "node.featuredImage.id");
originalIdString = GetJsonElementValue(jsonElement);
}
if (!string.IsNullOrEmpty(originalSrcString))
{
// do stuff
}
if (!string.IsNullOrEmpty(originalIdString))
{
// do stuff
}
}
I have developed a small library named JsonEasyNavigation, you can get it on github or from nuget.org. It allows you to navigate through JSON Domain Object Model using indexer-like syntax:
var jsonDocument = JsonDocument.Parse(json);
var nav = jsonDocument.ToNavigation();
ToNavigation() method converts JsonDocument into readonly struct named JsonNavigationElement. It has property and array item indexers, for example:
var item = nav["data"]["product"]["edges"][0];
Then you can check for actual items existince like this:
if (item.Exist)
{
var id = item["id"].GetStringOrEmpty();
// ...
}
I hope you will find it useful.
Thank Dave B for a good idea. I have improved it to be more efficient when accessing array elements without having to write too much code.
string raw = #"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
},
{
""node"": {
""id"": ""gid://shopify/Product/123456789"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": [
""gid://shopify/ProductImage/123456789"",
""gid://shopify/ProductImage/666666666""
]
},
""1"": {
""name"": ""Tuanh""
}
}
}
]
}
}
}";
Usage is also quite simple
JsonElement doc = JsonSerializer.Deserialize<JsonElement>(raw);
JsonElement jsonElementEdges = doc.GetJsonElement("data.products.edges.1.node.1.name");
public static JsonElement GetJsonElement(this JsonElement jsonElement, string path)
{
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
string[] segments = path.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
foreach (var segment in segments)
{
if (int.TryParse(segment, out var index) && jsonElement.ValueKind == JsonValueKind.Array)
{
jsonElement = jsonElement.EnumerateArray().ElementAtOrDefault(index);
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
continue;
}
jsonElement = jsonElement.TryGetProperty(segment, out var value) ? value : default;
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
}
return jsonElement;
}
public static string? GetJsonElementValue(this JsonElement jsonElement) => jsonElement.ValueKind != JsonValueKind.Null &&
jsonElement.ValueKind != JsonValueKind.Undefined
? jsonElement.ToString()
: default;
Depending on the type of JsonElement returned you have to handle it differently.
My case was that the returned element was ValueKind = Array : "[[47.751]]"
So in order to get it I did created this method
private object GetValueFromJsonElement(WorkbookRange range)
{
// The RootElement is the JsonElement
var element = range.Values.RootElement.EnumerateArray().First()[0];
switch (element.ValueKind)
{
case JsonValueKind.Number:
return element.GetDouble();
case JsonValueKind.String:
return element.GetString();
case JsonValueKind.True:
case JsonValueKind.False:
return element.GetBoolean();
default:
throw new InvalidOperationException("The Value Type returned is not handled");
}
}Depending on the type of JsonElement returned you have to handle it differently.
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
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
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}");
An extension method handling a simple case:
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.");
}
I wondered if it is possible to iterate over an ExpandoObject that contains an array of Expando Objects?
I am currently parsing some JSON with a file structure like the below:
"event":
[{
"name": "BEGIN!",
"count": 1
}],
"context":
{
"customer": {
"greetings":
[
{ "Value1": "Hello" },
{ "Value2": "Bye" }
],
"nicknames": []
}
}
I can retrieve the expando object for 'event' by doing the following:
GenerateDictionary(((ExpandoObject[])dict["event"])[0], dict, "event_");
This is the code for the GenerateDictionary method:
private void GenerateDictionary(System.Dynamic.ExpandoObject output, Dictionary<string, object> dict, string parent)
{
try
{
foreach (var v in output)
{
string key = parent + v.Key;
object o = v.Value;
if (o.GetType() == typeof(System.Dynamic.ExpandoObject))
{
GenerateDictionary((System.Dynamic.ExpandoObject)o, dict, key + "_");
}
else
{
if (!dict.ContainsKey(key))
{
dict.Add(key, o);
}
}
}
}
catch (Exception ex)
{
WritetoLog(itemname, ex);
}
}
I am now totally stuck on how to retrieve all the values in 'context_customer_greetings' as when I attempt to do the below, it will only retrieve the object at context_customer_greetings_value1.
GenerateDictionary(((System.Dynamic.ExpandoObject[])dict["context_customer_greetings"])[0], dict, "context_customer_greetings_");
Is it possible to iterate through an ExpandoObject?
I hope this makes sense, thanking you in advance.
I have now found a solution to this (albeit a simple one!)
I created a new dynamic object and then iterate across that using the same method above.
dynamic s = dict["context_custom_greetings"];
foreach(ExpandoObject o in s)
{
GenerateDictionary((ExpandoObject)o, dict, "context_custom_greetings_");
}
I have the following table:
I'd like to execute a LINQ Query that serializes:
JSON:
{
"product-list": {
"products": [
{
"P_Flavor": [
"Berry",
"Cedar",
"Cherry",
"Coffee"
],
"P_Winery": [
"Lyeth"
],
"P_Body": [
"Elegant",
"Firm",
"Firm Tannins",
"Polished",
"Supple",
"Tannins"
],
"P_Name": "A Red Blend",
"P_DateReviewed": "08/31/95",
"P_WineID": 34699,
"P_Score": 5,
}
]
}
}
I would normally use JavaScriptSerializer to do this, however I would like to construct my own JSON payload.
IList<record_property> recList = (from c in entities.record_property
select c).ToList();
var json = new JavaScriptSerializer().Serialize(recList);
What would be the best way to do this?
There may be a quicker/more concise way to do this, but I did it by combining a JavaScriptConverter with a helper type.
The converter (simpler than it looks, inspired from here):
private class RecordPropertyJavaScriptConverter : JavaScriptConverter
{
private static readonly Type[] _supportedTypes = new[]
{
typeof(record_group)
};
public override IEnumerable<Type> SupportedTypes
{
get { return _supportedTypes; }
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (type == typeof(record_group))
{
record_group obj = new record_group();
var kvp = dictionary.Single();
obj.Key = kvp.Key;
obj.Values = serializer.ConvertToType<IEnumerable<object>>(kvp.Value);
return obj;
}
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var dataObj = obj as record_group;
if (dataObj != null)
{
return new Dictionary<string, object>
{
{dataObj.Key, dataObj.Values}
};
}
return new Dictionary<string, object>();
}
}
The helper type:
private class record_group
{
public string Key;
public IEnumerable<object> Values;
}
The serialization code:
var groups = recList.GroupBy(r => r.Key)
.Select(g => new record_group { Key = g.Key, Values = g.Select(r => r.Value) });
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new [] {new RecordPropertyJavaScriptConverter()});
string json = serializer.Serialize(groups);
The output (with some tabs, newlines added by me):
[{"P_Flavor":["Berry","Cedar","Cherry","Coffee"]},
{"P_Winery":["Lyeth"]},
{"P_Body":["Elegant","Firm","Firm Tannins","Polished","Supple","Tannins"]},
{"P_Name":["A Red Blend"]},
{"P_DateReviewed":["08/31/95"]},
{"P_WineID":[34699]},
{"P_Score":[5]}]
Deserialization can then be done (using the same serializer instance from above) as follows:
var deserialized = serializer.Deserialize<IEnumerable<record_group>>(json);
var properties = deserialized.SelectMany(g => g.Values.Select(v => new record_property { Key = g.Key, Value = v }));
I have a string representing JSON and I want to rename some of the properties using JSON.NET. I need a generic function to use for any JSON. Something like:
public static void Rename(JContainer container, Dictiontionary<string, string> mapping)
{
foreach (JToken el in container.Children())
{
JProperty p = el as JProperty;
if(el != null && mapping.ContainsKey(p.Name))
{
// **RENAME THIS NODE!!**
}
// recursively rename nodes
JContainer pcont = el as JContainer;
if(pcont != null)
{
Rename(pcont, mapping);
}
}
}
How to do it??
I would suggest reconstructing your JSON with renamed properties. I don't think you should worry about speed penalties as it's usually not an issue. Here's how you can do it.
public static JToken Rename(JToken json, Dictionary<string, string> map)
{
return Rename(json, name => map.ContainsKey(name) ? map[name] : name);
}
public static JToken Rename(JToken json, Func<string, string> map)
{
JProperty prop = json as JProperty;
if (prop != null)
{
return new JProperty(map(prop.Name), Rename(prop.Value, map));
}
JArray arr = json as JArray;
if (arr != null)
{
var cont = arr.Select(el => Rename(el, map));
return new JArray(cont);
}
JObject o = json as JObject;
if (o != null)
{
var cont = o.Properties().Select(el => Rename(el, map));
return new JObject(cont);
}
return json;
}
And here's an example of usage:
var s = #"{ ""A"": { ""B"": 1, ""Test"": ""123"", ""C"": { ""Test"": [ ""1"", ""2"", ""3"" ] } } }";
var json = JObject.Parse(s);
var renamed = Rename(json, name => name == "Test" ? "TestRenamed" : name);
renamed.ToString().Dump(); // LINQPad output
var dict = new Dictionary<string, string> { { "Test", "TestRenamed"} };
var renamedDict = Rename(json, dict);
renamedDict.ToString().Dump(); // LINQPad output
We use this approach. You can find the property you want using JObject's SelectToken(). Yes it does support JsonPath.
public static class NewtonsoftExtensions
{
public static void Rename(this JToken token, string newName)
{
var parent = token.Parent;
if (parent == null)
throw new InvalidOperationException("The parent is missing.");
var newToken = new JProperty(newName, token);
parent.Replace(newToken);
}
}