0

Consider the following program: (.NET Fiddle Link)

public class Program
{
    public static void Main()
    {
        var carsa = new ListOfCarsA();
        carsa.Cars.Add("Toyota");
        carsa.Cars.Add("Lexus");
        Console.WriteLine(JsonConvert.SerializeObject(carsa, Formatting.Indented));

        var carsb = new ListOfCarsB();
        carsb.Add("Nissan");
        carsb.Add("Infiniti");
        Console.WriteLine(JsonConvert.SerializeObject(carsb, Formatting.Indented));
    }
}

public class ListOfCarsA
{
    public string CollectionName { get { return "CarsA"; } }
    public List<string> Cars { get; set; }

    public ListOfCarsA()
    {
        Cars = new List<string>();  
    }
}

public class ListOfCarsB : List<string>
{
    public string CollectionName { get { return "CarsB"; } }
}

This then outputs the following:

{ "CollectionName": "CarsA", "Cars": [ "Toyota", "Lexus" ] }

And

[ "Nissan", "Infiniti" ]

Why does the property CollectionName not get serialised and output CarsB, but the same property on the ListOfCarsA results in CarsA being serialised?

What is the solution to this problem - How could I have a class similar to ListOfCarsB but still have any extra members serialised? I have tried using the attributes [JsonProperty("CollectionName"] and [JsonRequired] but these seem to do nothing.

Danny Goodall
  • 798
  • 1
  • 9
  • 33
  • 3
    That is by design. The framework treats IEnumerables as collections and serializes them as JSON arrays. Your ListOfCarsB is a derived collection. All other properties are ignored. Same reason you do not see `List.Count` property being shown. – Nkosi Dec 11 '17 at 15:41
  • 1
    Also, read [Why not inherit from `List`?](https://stackoverflow.com/questions/21692193/why-not-inherit-from-listt?rq=1) – Camilo Terevinto Dec 11 '17 at 15:42
  • Are there any workarounds? @Nkosi – Danny Goodall Dec 11 '17 at 15:43
  • 2
    There's nothing in JSON that represents "a collection of values and some other properties". If you want that, use compisition as per ListOfCarsA. – Jon Skeet Dec 11 '17 at 15:46
  • @DannyGoodall not that I know of. What would your desired output look like? – Nkosi Dec 11 '17 at 15:46
  • A simpler organization would be to take `ListOfCarsA` and make it `ListOfCars` with the `CollectionName` being settable. Then you don't need an `A` or `B` class. – crashmstr Dec 11 '17 at 15:56

1 Answers1

0

This is because your second example IS a list, whilst the first example only contains one. Json.Net knows how to create json from lists and so is ignoring the rest of your custom code. Not much you can do about this except write a custom formatter

Chris Surfleet
  • 2,462
  • 4
  • 28
  • 40