Есть ли библиотека Json, которая работает как с массивом объектов, так и с массивом абстрактных классов?

Мне нужно читать / писать Json из / в POCO, который украшен атрибутами XmlSerialization. Это POCO было сгенерировано из XSD. Он широко использует полиморфизм, наследование, объекты, массивы объектов и массив абстрактных классов. Я уже попробовал JsonFx V2, который выглядел очень многообещающе, но, к сожалению, это не работает хорошо, и в течение нескольких лет практически нет активности в этом проекте с открытым исходным кодом.

Любая помощь приветствуется.

Обновление 1: AFAIK Json.NET не знает, как обращаться с атрибутами XmlSerialization.

Обновление 2: ServiceStack V3, кажется, выполняет свою работу, но у меня есть по крайней мере одна проблема.

Элемент _type добавляется, когда свойство имеет тип объекта, что нормально. Но нет такой информации для массива объекта.

Рассмотрим следующие классы C#:

[System.Xml.Serialization.XmlIncludeAttribute(typeof(adxppostalCode))]
public partial class ADXP : ST
{
  ...
}

а также

[System.Xml.Serialization.XmlTypeAttribute(TypeName = "adxp.postalCode"]
public partial class adxppostalCode : ADXP
{
}

Если массив объекта (object[]) содержит экземпляр adxppostalCode, информация о типе не помещается в Json при сериализации. Следовательно, он добавляет экземпляр класса ADXP в массив при десериализации вместо экземпляра adxppostalCode.

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

Удапта 3. После некоторого дополнительного тестирования выясняется, что Json.NET (по крайней мере, версия 7.0.1 Beta 3) поддерживает атрибуты и выдает правильную информацию о типе для массива объектов (пространство имен и имя библиотеки были удалены).

"Items": [
              {
                "$type": "adxppostalCode, ....",
                "mediaType": "text/plain",
                "compressionSpecified": false,
                "integrityCheckAlgorithm": 0,
                "representation": 1,
                "Text": [
                  "69110"
                ]
              }
            ]

Для массива абстрактного класса правильный вывод записывается в выводе. При десериализации он пытается создать экземпляр базового типа, который является абстрактным, и он терпит неудачу. Например:

Json фрагмент:

"Items": [
          {
            "$type": "IVXB_TS, ...",
            "inclusive": true,
            "value": "20091231"
          }
        ]

Не удалось создать экземпляр типа QTY. Тип является интерфейсом или абстрактным классом и не может быть создан.

Иерархия классов:

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class ANY : object, System.ComponentModel.INotifyPropertyChanged
{
}

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class QTY : ANY
{
}

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public partial class TS : QTY
{
}

public partial class IVXB_TS : TS
{
}

Массив абстрактного класса:

[System.Xml.Serialization.XmlElementAttribute("high", typeof(IVXB_TS))]
[System.Xml.Serialization.XmlElementAttribute("low", typeof(IVXB_TS))]
public QTY[] Items

1 ответ

Решение

Ну, Json.NET 7.0.1 Beta 3 на самом деле способен справиться со всеми этими случаями.

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

Может быть, более ранняя версия будет делать то же самое.

Другие вопросы по тегам