5

I'm using .NET's JavascriptSerializer to deserialize JSON into runtime objects and for the most part the mapping between JSON fields and object fields has been automatic. However, I am faced with the following scenario and would welcome advice on how to handle it.

Imagine we have a JSON representation of a Shape, which can be a Square or a Circle. For example,

{"ShapeType":"Circle","Shape":{"Color":"Blue", "Radius":"5.3"}}

or

{"ShapeType":"Square","Shape":{"Color":"Red", "Side":"2.1"}}

These JSON strings are modeled after the class hierarchy shown below.

class ShapePacket
{
    public string ShapeType;  // either "Square" or "Circle"
    public Shape Shape;
}

class Shape   // all Shapes have a Color
{
    public string Color;
}

class Square : Shape
{
    public float Side;
}

class Circle : Shape
{
    public float Radius;
}

Simply calling JavascriptSerializer.Deserialize doesn't work in this case, where there is a variant type involved. Is there any way to coax JavascriptSerializer to deserialize despite the "branch" in my data type? I am also open to third-party solutions.

I. J. Kennedy
  • 24,725
  • 16
  • 62
  • 87
  • Looks similar to this question [JSON serialization of array with polymorphic objects](http://stackoverflow.com/questions/5186973/json-serialization-of-array-with-polymorphic-objects). – Roman Apr 08 '11 at 17:40

2 Answers2

2

The branch in your data type likely necessitates a branch in your code. I don't believe there's a way to do this besides the explicit way.

I would do this in two steps:

First, turn the incoming JSON object into a typeless hash using JsonConvert.DeserializeObject

Then, manually branch on the 'ShapeType' field to choose the appropriate Shape class (Square or Circle), and construct an instance yourself.

(explicit solution included here for posterity, although I suspect you don't need my help with it ;)

Kyle Wild
  • 8,845
  • 2
  • 36
  • 36
1

I think you need to initialize the JavascriptSerializer with a JavaScriptTypeResolver implementation like this (SimpleTypeResolver is built-in in the class library):

new JavaScriptSerializer(new SimpleTypeResolver());

in order to enable automatic type resolution. I think as a result it will add a __type field to the output JSON, which it will later use to resolve back the type.

Ivan Zlatev
  • 13,016
  • 9
  • 41
  • 50