¿Cómo obtengo json.net para serializar miembros de una clase derivada de List ?

PagedResult : List una clase PagedResult : List que contiene algunos miembros adicionales para poder trabajar con uno de nuestros componentes. Sin embargo, cuando ejecuto el deserializador json, solo serializa la lista. Si [JsonObject] clase derivada con [JsonObject] y [JsonProperty] , solo serializará los miembros de la clase derivada y no la lista. ¿Cómo puedo obtener ambos?

De forma predeterminada, Json.Net tratará cualquier clase que implemente IEnumerable como una matriz. Puede anular este comportamiento decorando la clase con un atributo [JsonObject] , pero solo las propiedades del objeto se serializarán, como ha visto. La lista en sí no se serializará porque no está expuesta a través de una propiedad pública (más bien, está expuesta a través del método GetEnumerator() ).

Si desea ambas cosas, puede hacer lo que @Konrad ha sugerido y proporcionar una propiedad pública en su clase derivada para exponer la lista, o puede escribir un JsonConverter personalizado para serializar todo como mejor le parezca. Un ejemplo de este último enfoque sigue.

Suponiendo que su PagedResult parece a esto:

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

Puedes hacer un convertidor para esto así:

 class PagedResultConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(PagedResult)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { PagedResult result = (PagedResult)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(); } } 

(Observe también que los [JsonObject] y [JsonProperty] no son necesarios con este enfoque, porque el conocimiento de qué serializar se encapsula en la clase de convertidor).

Aquí hay una demostración que muestra el convertidor en acción:

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

Salida:

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

La solución más simple que me viene a la mente es exponer los elementos internos como otra propiedad de la clase derivada:

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