Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
538 views
in Technique[技术] by (71.8m points)

c# - Excluding specific items in a collection when serializing to JSON

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

Example setup:

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 the courses in the Person.Courses collection where ShouldSerialize is false. This needs to be done from within the ContractResolver - the ShouldSerialize property is an example, in my real scenario there may be other criteria. I'd prefer not having to create a ShouldSerializeCourse (as specified here: http://james.newtonking.com/json/help/index.html?topic=html/ConditionalProperties.htm )

I can't seem to find out which method to override in the ContractResolver. How would I go about this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't think you can filter a list using a ContractResolver, but you could do it using a 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"
      }
    ]
  }
]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...