Json.net rename properties
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);
}
}
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