如何让json.net序列化从List <T>派生的类的成员?

我创build了一个类PagedResult<T> : List<T> ,其中包含一些添加的成员,以便与我们的组件之一一起工作。 但是,当我运行JSON解串器时,它只是序列化列表。 如果我用[JsonObject][JsonProperty]标记派生类,那么它将只序列化派生类的成员,而不是列表。 我如何得到两个?

默认情况下,Json.Net将把任何实现了IEnumerable类作为一个数组。 您可以通过使用[JsonObject]属性修饰类来覆盖此行为,但是只有对象属性才会被序列化,如您所见。 列表本身不会被序列化,因为它没有通过公共属性公开(而是通过GetEnumerator()方法公开)。

如果你同时想,你可以像@Konrad所build议的那样做,并且在你的派生类上提供一个公共属性来暴露这个列表,或者你可以编写一个自定义的JsonConverter来按照你认为合适的方式序列化整个事物。 后面的方法的一个例子如下。

假设你的PagedResult<T>类看起来像这样:

 class PagedResult<T> : List<T> { public int PageSize { get; set; } public int PageIndex { get; set; } public int TotalItems { get; set; } public int TotalPages { get; set; } } 

你可以像这样做一个转换器:

 class PagedResultConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(PagedResult<T>)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { PagedResult<T> result = (PagedResult<T>)value; JObject jo = new JObject(); jo.Add("PageSize", result.PageSize); jo.Add("PageIndex", result.PageIndex); jo.Add("TotalItems", result.TotalItems); jo.Add("TotalPages", result.TotalPages); jo.Add("Items", JArray.FromObject(result.ToArray(), serializer)); jo.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } 

(还要注意,这种方法不需要[JsonObject][JsonProperty]属性,因为序列化内容被封装到转换器类中。)

下面是演示转换器的演示:

 class Program { static void Main(string[] args) { PagedResult<string> result = new PagedResult<string> { "foo", "bar", "baz" }; result.PageIndex = 0; result.PageSize = 10; result.TotalItems = 3; result.TotalPages = 1; JsonSerializerSettings settings = new JsonSerializerSettings(); settings.Converters.Add(new PagedResultConverter<string>()); settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(result, settings); Console.WriteLine(json); } } 

输出:

 { "PageSize": 10, "PageIndex": 0, "TotalItems": 3, "TotalPages": 1, "Items": [ "foo", "bar", "baz" ] } 

我想到的最简单的解决方法是将内部元素作为派生类的另一个属性公开:

 [JsonProperty] public IEnumerable<T> Elements { get { return this; } }