序列化为JSON时排除集合中的特定项

时间:2014-01-06 17:32:03

标签: c# .net json json.net

我正在尝试“挑选”我要序列化的特定类型集合中的哪些对象。

示例设置:

public class Person
{
    public string Name { get; set; }

    public List<Course> Courses { get; set; }
}

public class Course
{
    ...

    public bool ShouldSerialize { get; set; }
}

我需要能够排除Person.Courses集合中ShouldSerialize为false的所有课程。这需要在ContractResolver中完成 - ShouldSerialize属性就是一个例子,在我的实际场景中可能还有其他标准。我不想创建一个ShouldSerializeCourse(如此处所指定:http://james.newtonking.com/json/help/index.html?topic=html/ConditionalProperties.htm

我似乎无法找出ContractResolver中要覆盖的方法。我该怎么做呢?

2 个答案:

答案 0 :(得分:7)

我认为您不能使用ContractResolver过滤列表,但您可以使用自定义JsonConverter来完成。这是一个例子:

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

输出:

[
  {
    "Name": "John",
    "Courses": [
      {
        "Name": "Trigonometry"
      },
      {
        "Name": "History"
      }
    ]
  },
  {
    "Name": "Georgia",
    "Courses": [
      {
        "Name": "Spanish"
      },
      {
        "Name": "Geography"
      }
    ]
  }
]

答案 1 :(得分:0)

您不应该将逻辑放入序列化程序。而是过滤集合,然后序列化它。在这种情况下,您可以使用类似这样的内容

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

return Person;

如果您真的需要将合约解析器添加到序列化程序中,您可以在Global.asax.cs中进行(假设您使用的是asp.net)