Search code examples
c#jsonfacebookserializationdatacontractserializer

Can I control what subtype to use when deserializing a JSON string?


I'm working with Facebook API and it's search method returns a JSON response like this:

{
   "data": [
      {
         "id": "1",
         "message": "Heck of a babysitter...",
         "name": "Baby eating a watermelon",
         "type": "video"
      },
      {
         "id": "2",
         "message": "Great Produce Deals",
         "type": "status"
      }
   ]
}

I have a class structure similar to this:

[DataContract]
public class Item
{
    [DataMember(Name = "id")]
    public string Id { get; set; }
}

[DataContract]
public class Status : Item
{
    [DataMember(Name = "message")]
    public string Message { get; set; }
}

[DataContract]
public class Video : Item
{
    [DataMember(Name = "string")]
    public string Name { get; set; }

    [DataMember(Name = "message")]
    public string Message { get; set; }
}

[DataContract]
public class SearchResults
{
    [DataMember(Name = "data")]
    public List<Item> Results { get; set; }
}

How can I use correct subclass based on that type attribute?


Solution

  • If you use the

    System.Web.Script.Serialization.JavaScriptSerializer
    

    you can use the overload in the constructor to add your own class resolver:

    JavaScriptSerializer myserializer = new JavaScriptSerializer(new FacebookResolver());
    

    An example how to implement this can be found here on SO: JavaScriptSerializer with custom Type

    But you should replace the

    "type": "video"
    

    part to

    "__type": "video"
    

    since this is the convention for the class.

    Here is an example:

    public class FacebookResolver : SimpleTypeResolver
    {
        public FacebookResolver() { }
        public override Type ResolveType(string id)
        {
            if(id == "video") return typeof(Video);
            else if (id == "status") return typeof(Status)
            else return base.ResolveType(id);
        }
    }