Ok, we\'re using Newtonsoft\'s JSON.NET product, which I really love. However, I have a simple class structure for hierarchical locations that look roughly like this...
Ok... so here's what I've come up with. I had to write my own JsonConverter. I basically use it to create an inline JObject that has the properties structured as I wanted them to persist, then I persist that. I then do the reverse when I read it back out.
However, the down'side is it doesn't use reflection or any other such things so this only works for this specific type which I had to hand-code property by property (in this case there are only two so that's good!) and it also doesn't take advantage of the DefaultValues processing which I have to re-emulate manually, meaning the attributes are basically ignored unless I reflect upon them. Still, this works. Perfect? No, but hey... things rarely are!
Of course, comments are welcome and encouraged!
public class LocationListJsonConverter : JsonConverter
{
public override bool CanConvert(System.Type objectType)
{
return objectType == typeof(LocationList);
}
public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
{
var locationList = (existingValue as LocationList) ?? new LocationList();
var jLocationList = JObject.ReadFrom(reader);
locationList.IsExpanded = (bool)(jLocationList["IsExpanded"] ?? false);
var jLocations = jLocationList["_Items"];
if(jLocations != null)
{
foreach(var jLocation in jLocations)
{
var location = serializer.Deserialize(new JTokenReader(jLocation));
locationList.Add(location);
}
}
return locationList;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var locationList = value as LocationList;
JObject jLocationList = new JObject();
if(locationList.IsExpanded)
jLocationList.Add("IsExpanded", true);
if(locationList.Count > 0)
{
var jLocations = new JArray();
foreach(var location in locationList)
{
jLocations.Add(JObject.FromObject(location, serializer));
}
jLocationList.Add("_Items", jLocations);
}
jLocationList.WriteTo(writer);
}
}