2

I have a class with the following fields.

public class Payment
{
    public string type { get; set; }
    public string issuer { get; set; }
    public string identifier { get; set; }
    public float price { get; set; }
}

The "type" field can be "Giftcard" or "Creditcard".
I want to serialize it depends on the "type" field.

{
   "type": "Giftcard",
   "giftcard_no": "111111111111",
   "giftcard_price": 100
}
{
   "type": "Creditcard",
   "issuer": "AMEX",
   "last_4_digits": "1000",
   "creditcard_price": 100
}

As you can see, the field names are different depends on the "type" field.
And "issuer" field is ignored in case of Giftcard.

I've found similar questions, but couldn't find the correct answer.
I will be appreciated for any help.

Thank you.

dbc
  • 104,963
  • 20
  • 228
  • 340
Shi J
  • 85
  • 5

1 Answers1

4

It sounds to me like what you want is different subclasses, using type to determine which one to use when deserializing. I've found that the JsonSubTypes package (GitHub repo) works very well for this.

You'd have something like this:

[JsonConverter(typeof(JsonSubtypes), "type")]
[JsonSubtypes.KnownSubType(typeof(GiftCard), "Giftcard")]
[JsonSubtypes.KnownSubType(typeof(CreditCard), "Creditcard")]
public class Payment
{
    [JsonProperty("type")]
    public virtual string Type { get; }
}

public class CreditCard : Payment
{
    public override string Type => "Creditcard";

    [JsonProperty("issuer")
    public string Issuer { get; set; }

    // Etc, other properties
}

public class GiftCard : Payment
{
    public override string Type => "Giftcard";

    [JsonProperty("giftcard_no")]
    public string GiftCardNumber { get; set; }

    // Etc, other properties
}

There are various different options for exactly how you register things - the README on the GitHub repo gives concrete examples, which is really useful.

You'd then deserialize to Payment, but the returned value would be a reference to an instance of GiftCard or CreditCard.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yup :) i think its getting a bit late for me on a Friday to be answering questions (or even commenting) +1 – TheGeneral Aug 21 '20 at 09:01
  • I think I prefer the custom `JsonConverter` but this is pretty neat too, thanks for introducing this library to me. – DavidG Aug 21 '20 at 09:02
  • @DavidG: I generally prefer a solution where someone else has already written and tested the code for me :) (I mean, this *is* a custom `JsonConverter`, just one that's already been written.) – Jon Skeet Aug 21 '20 at 09:22
  • Thank you a lot for your quick and perfect answer, Jon. Thanks again!!! – Shi J Aug 21 '20 at 09:30