using System.Collections.Generic;
public static void Main()
InvoiceDetail = new List<IInvoiceDetail>
new InvoiceDetail { Item = "a", Price = 1, },
new InvoiceDetail { Item = "b", Price = 2, },
VatDetail = new List<IVatDetail>
new VatDetail { Rate = 0.10M, Amount = 1, },
new VatDetail { Rate = 0.20M, Amount = 2, },
var json = JsonConvert.SerializeObject(invoice, Formatting.Indented);
var newInvoice = JsonConvert.DeserializeObject<test>(json);
Console.WriteLine(JsonConvert.SerializeObject(newInvoice, Formatting.Indented));
public class InvoiceDetailConverter<TConcrete, TInterface> : JsonConverter where TConcrete : TInterface
public override bool CanConvert(Type objectType)
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
List<TConcrete> data = serializer.Deserialize<List<TConcrete>>(reader);
List<TInterface> result = new List<TInterface>();
foreach (TInterface d in data)
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
serializer.Serialize(writer, value);
public interface IInvoiceDetail
string Item { get; set; }
public class InvoiceDetail : IInvoiceDetail
public string Item { get; set; }
public int Price { get; set; }
public interface IVatDetail
decimal Rate { get; set; }
public class VatDetail : IVatDetail
public decimal Rate { get; set; }
public int Amount { get; set; }
[JsonConverter(typeof(InvoiceDetailConverter<InvoiceDetail, IInvoiceDetail>))]
public List<IInvoiceDetail> InvoiceDetail { get; set; }
[JsonConverter(typeof(InvoiceDetailConverter<VatDetail, IVatDetail>))]
public List<IVatDetail> VatDetail { get; set; }