Is there any way to JSON.NET-serialize a subclass of List that also has extra properties?

前端 未结 3 1974
没有蜡笔的小新
没有蜡笔的小新 2020-12-17 19:26

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...

3条回答
  •  长情又很酷
    2020-12-17 19:59

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

提交回复
热议问题