2

I have a .NET REST web-service that sends JSON data to various mobile apps.

I am testing a new method which returns objects that could be one of several subclasses, for example in the following pseudo-code it could return:

wallet: {
  cards: [ { name: 'mastercard', ...},
           { name: 'visacard', ...},
           { name: 'photocard', ...}
  ]
}

where each card is a SubClass of Card, e.g.

public abstract class Card
{
  ...
}
public class CreditCard : Card 
{
  ...
}
public class ConcessionCard : Card
{
  ...
}

public string webServiceMethodGetWallet()
{
  myWallet = new Wallet();
  CreditCard visaCard = new CreditCard();
  CreditCard masterCard = new CreditCard();
  ConcessionCard photoCard = new ConcessionCard();
  myWallet.cards.AddAll(visaCard, masterCard, photoCard);
  return JSON.Serialize(myWallet);  
}

I am deserializing this data on multiple platforms (iOS, Android and Windows Phone).

What is a good strategy to let the client apps know which class to use for each of the objects when deserializing? e.g. in the above example, how can the client app tell whether to create classes of type CreditCard or ConcessionCard without inspecting all the fields?

Bear in mind, I need to deserialize in Objective C, Java and .NET.

Is there a 'normal' way of doing this?

Carlos P
  • 3,928
  • 2
  • 34
  • 50
  • Can't speak for Obj-C or Java, but for .NET - if you use Json.Net, you can include a `$type` property (has to be the first property) in the JSON that Json.Net uses as a hint to the de-serialiser as to what the target type should be. – Stephen Byrne Feb 07 '14 at 16:47
  • Thanks - I am hoping that there may be a cross-platform solution, or a standard way of doing it, since my experiences with JSON are a little limited. – Carlos P Feb 07 '14 at 17:47
  • I also found this re. Objective-C: http://stackoverflow.com/questions/14958883/ios-serialize-deserialize-complex-json-generically-from-nsobject-class. I don't understand it :) but it does seem to deal with mapping json to a specifc type based on a property in the json itself. Hope that helps. – Stephen Byrne Feb 08 '14 at 01:05
  • and this article: http://programmerbruce.blogspot.ie/2011/05/deserialize-json-with-jackson-into.html would appear to be how it can be done in Java. So overall, you will probably want some way for the clients to tell the server what "format" of json they want as each of the three examples uses a different way of identifying the type mapping... – Stephen Byrne Feb 08 '14 at 01:09

1 Answers1

1

How about splitting the one collection into separate arrays (of strong types) in the JSON?

Like this:

wallet: {
  CreditCards: [ { name: 'mastercard', ...},
           { name: 'visacard', ...}
  ],
  ConcessionCards: [ { name: 'photocard', ...}
  ]
}

That way if any are not present, the deserializer would just leave them as null.

Tom Florkiewicz
  • 642
  • 3
  • 9
  • This seems inefficient, because you need to create an array for each subclass, and then modify the containing object to add a new array every time you add a new subclass. It also doesn't deal very well with the usage case of creating a subclass of a subclass. But perhaps it's the only approach that makes sense. Comments encouraged. – Carlos P Feb 07 '14 at 21:10