DataContractJsonSerializer Проблема десериализации - PullRequest
0 голосов
/ 09 сентября 2018

Мне нужно десериализовать массив Json, который указан ниже ....

[
    {
        "GeoType": 1,
        "ID": "2650f7d2-7a5e-4b63-856c-07600fa2a854",
        "Name": "Afghanistan",
        "CapitalCity": null,
        "CountryBoundaries": null,
        "CountryCode": "AF",
        "ISO": "AFG",
        "Parent": {
            "__type": "Region:#MEDEX.Library.Geo",
            "GeoType": 0,
            "ID": "6dc22edb-d711-4253-937f-242b0cd3c011",
            "Name": "Asia",
            "Code": "Asi"
        },
        "RegionID": "6dc22edb-d711-4253-937f-242b0cd3c011"
    },
    {
        "GeoType": 1,
        "ID": "3917c1c8-ee01-4e9b-8622-0fac9e9194ab",
        "Name": "Albania",
        "CapitalCity": null,
        "CountryBoundaries": null,
        "CountryCode": "AL",
        "ISO": "ALB",
        "Parent": {
            "__type": "Region:#MEDEX.Library.Geo",
            "GeoType": 0,
            "ID": "b7ebd500-45e6-4a48-a2ef-f38fe99e7352",
            "Name": "Europe",
            "Code": "Eur"
        },
        "RegionID": "b7ebd500-45e6-4a48-a2ef-f38fe99e7352"
    }
]

Мое определение объекта:

[DataContract]
public class Parent1
{
    [DataMember]
    public Dictionary<string, Type> __type { get; set; }
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string GeoType { get; set; }
    [DataMember]
    public string Code { get; set; }
}

[DataContract]
public class Country
{
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string GeoType { get; set; }
    [DataMember]
    public Parent1 Parent { get; set; }
    [DataMember]
    public string RegionID { get; set; }
    [DataMember]
    public string CountryCode { get; set; }
    [DataMember]
    public string ISO { get; set; }
}

всегда появляется ошибка:

{"Элемент": Родитель "содержит данные из типа, который сопоставляется с именем 'http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo:Region'. Десериализатор не знает ни о каком типе, который сопоставляется с этим именем. Рассмотрите возможность использования DataContractResolver, если вы используете DataContractSerializer или добавьте тип, соответствующий 'Region', в список известных типов - например, с помощью атрибута KnownTypeAttribute или добавив его в список известных типов, передаваемых сериализатору. "}

Не могли бы вы предложить мне какое-либо решение. Я даже не понимаю, что означает эта ошибка. Пожалуйста, предложите.

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Как объяснено в этом ответе на parse.com: SerializationException десериализация объектов JSON со свойством "__type" , ваша проблема в том, что "__type" зарезервированное свойство для DataContractJsonSerializer. Он используется для идентификации производных типов полиморфных типов. Из документов :

Сохранение информации о типе

Чтобы сохранить идентичность типа, при сериализации сложных типов в JSON можно добавить «подсказку типа», и десериализатор распознает подсказку и будет действовать соответствующим образом. «Тип подсказка» представляет собой пару ключ / значение JSON с именем ключа «__type» (два подчеркивания, за которыми следует слово «тип»). Значением является строка в формате JSON в форме «DataContractName: DataContractNamespace» (имя до любого двоеточия является именем) ...

Подсказка типа очень похожа на атрибут xsi: type, определенный стандартом экземпляра схемы XML и используемый при сериализации / десериализации XML.

Запрещено использование элементов данных с именем "__type" из-за возможного конфликта с подсказкой типа.

Таким образом, вы не можете вручную добавить это свойство в свой класс и заставить его правильно переводить.

Однако вы можете использовать обработку полиморфизма сериализатора для автоматического считывания и записи "__type" , определив иерархию классов областей, в которых класс Region наследуется от некоторого базового типа, скажем RegionBase, на что ссылается Country.Parent:

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Country
{
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string GeoType { get; set; }

    [DataMember]
    public RegionBase Parent { get; set; }

    [DataMember]
    public string RegionID { get; set; }
    [DataMember]
    public string CountryCode { get; set; }
    [DataMember]
    public string ISO { get; set; }
}

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
[KnownType(typeof(Region))]
public class RegionBase
{
}

[DataContract(
    Name = "Region", 
    Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Region : RegionBase
{
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string GeoType { get; set; }
    [DataMember]
    public string Code { get; set; }
}

Затем десериализуйте как List<Country>, поскольку ваш внешний JSON-контейнер является массивом.

Примечания:

0 голосов
/ 09 сентября 2018

Добавить [KnownType (Region)] к атрибутам класса Parent1

...