Как работать с JSON и вариантами объектов? - PullRequest
5 голосов
/ 08 апреля 2011

Я использую .NET JavascriptSerializer для десериализации JSON в объекты времени выполнения, и по большей части отображение между полями JSON и полями объекта было автоматическим. Однако я столкнулся со следующим сценарием и хотел бы получить совет о том, как с ним справиться.

Представьте, что у нас есть JSON-представление Shape, которое может быть квадратом или кругом. Например,

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

или

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

Эти строки JSON смоделированы после иерархии классов, показанной ниже.

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;
}

Простой вызов JavascriptSerializer.Deserialize не работает в этом случае, когда задействован тип варианта. Есть ли способ уговорить JavascriptSerializer на десериализацию, несмотря на «ветвь» в моем типе данных? Я также открыт для сторонних решений.

Ответы [ 2 ]

2 голосов
/ 08 апреля 2011

Ответвление в вашем типе данных, вероятно, требует ответвления в вашем коде.Я не верю, что есть способ сделать это, кроме явного способа.

Я бы сделал это в два этапа:

Во-первых, включите входящий объект JSON вхэш без типа с использованием JsonConvert.DeserializeObject

Затем вручную перейдите в поле ShapeType, чтобы выбрать соответствующий класс Shape (Square или Circle), и создайте экземпляр самостоятельно.

(явное решение включено сюда для потомков, хотя я подозреваю, что вам не нужна моя помощь с ним;)

1 голос
/ 08 апреля 2011

Я думаю, вам нужно инициализировать JavascriptSerializer с помощью реализации JavaScriptTypeResolver, как это (SimpleTypeResolver встроен в библиотеку классов):

new JavaScriptSerializer(new SimpleTypeResolver());

, чтобы включить автоматическое разрешение типов.Я думаю, что в результате он добавит поле __type к выходному JSON, который он позже будет использовать для разрешения типа.

...