Search code examples
c#serializationjsonconvert

How to serialize json in order to display property value instead of property name?


I am trying to find a way to serialize object to json string in the following format, so I can meet project requirements

{
  "id": 123456,
  "los": {
    "2019-05-13": [
      {
        "currency": "EUR",
        "guests": 2,
        "price": [
          100,
          200
        ]
      },
      {
        "currency": "EUR",
        "guests": 3,
        "price": [
          150,
          250
        ]
      }
    ],
    "2019-05-14": {
      "currency": "EUR",
      "guests": 2,
      "price": [
        300
      ]
    }
  },
}

I created these model classes:

public class Rootobject
{
    public Los los { get; set; }
    public int Id { get; set; }
}

public class Los
{
    public Item[] items{ get; set; }
}

public class Item
{
    public DateTime date {get;set;}
    public string currency { get; set; }
    public int guests { get; set; }
    public int[] price { get; set; }
}

It is possible somehow to change the name of an element during serialization, so Item is serialized as "2019-05-13", "2019-05-14" etc?


Solution

  • To do this, you need this class structure:

    public class Rootobject
    {
        public int Id { get; set; }
        [JsonConverter(typeof(CustomItemConverter))]
        public Dictionary<DateTime, Item[]> Los { get; set; }
    }
    
    public class Item
    {
        [JsonIgnore]
        public DateTime Date { get; set; }
        public string Currency { get; set; }
        public int Guests { get; set; }
        public int[] Price { get; set; }
    }
    

    and custom converter:

    public class CustomItemConverter : JsonConverter
    {
        public override bool CanRead => false;
    
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Dictionary<DateTime, Item[]>);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var dictionary = (Dictionary<DateTime, Item[]>)value;
    
            writer.WriteStartArray();
            foreach (var item in dictionary)
            {
                writer.WriteStartObject();
                writer.WritePropertyName(item.Key.Date.ToString("yyyy-MM-dd"));
                serializer.Serialize(writer, item.Value);
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
        }
    }