Exclusion of individual items in a collection when serialized in JSON

I am trying to "pick a cherry" which objects in a collection of a particular type I want to serialize.

Setting example:

public class Person { public string Name { get; set; } public List<Course> Courses { get; set; } } public class Course { ... public bool ShouldSerialize { get; set; } } 

I need to be able to exclude all courses from the Person.Courses collection, where AlwaysSerialize is false. This must be done from within the ContractResolver - an example is the ShouldSerialize property, there may be other criteria in my real scenario. I would prefer it not be necessary to create ShouldSerializeCourse (as indicated here: http://james.newtonking.com/json/help/index.html?topic=html/ConditionalProperties.htm ).

I cannot figure out which method to override in ContractResolver. How would I go about this?

+5
json c #
source share
2 answers

I do not think you can filter the list using ContractResolver, but you can do it using custom JsonConverter. Here is an example:

 class Program { static void Main(string[] args) { List<Person> people = new List<Person> { new Person { Name = "John", Courses = new List<Course> { new Course { Name = "Trigonometry", ShouldSerialize = true }, new Course { Name = "History", ShouldSerialize = true }, new Course { Name = "Underwater Basket Weaving", ShouldSerialize = false }, } }, new Person { Name = "Georgia", Courses = new List<Course> { new Course { Name = "Spanish", ShouldSerialize = true }, new Course { Name = "Pole Dancing", ShouldSerialize = false }, new Course { Name = "Geography", ShouldSerialize = true }, } } }; JsonSerializerSettings settings = new JsonSerializerSettings(); settings.Converters.Add(new CourseListConverter()); settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(people, settings); Console.WriteLine(json); } } class CourseListConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(List<Course>)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { serializer.Serialize(writer, ((List<Course>)value).Where(c => c.ShouldSerialize).ToArray()); } public override bool CanRead { get { return false; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } public class Person { public string Name { get; set; } public List<Course> Courses { get; set; } } public class Course { public string Name { get; set; } [JsonIgnore] public bool ShouldSerialize { get; set; } } 

Output:

 [ { "Name": "John", "Courses": [ { "Name": "Trigonometry" }, { "Name": "History" } ] }, { "Name": "Georgia", "Courses": [ { "Name": "Spanish" }, { "Name": "Geography" } ] } ] 
+7
source share

You should not enter logic into the serializer. Instead, filter the collection and then serialize it. In this case, you can use something like this

 Person.Courses = Person.Courses.Where(t=> t.ShouldSerialize == false); return Person; 

If you really need to add a contract recognizer to your serializer, you can do this in your Global.asax.cs file (if you use asp.net)

0
source share

All Articles