Удаление десериализации XML с помощью DataContractSerializer - программирование
Подтвердить что ты не робот

Удаление десериализации XML с помощью DataContractSerializer

У меня есть веб-служба, которая возвращает следующие данные:

<?xml version=""1.0"" encoding=""UTF-8""?>
<RESPONSE>
    <KEY>12345</KEY>
    <PROPERTY>
        <PROPERTY_ADDRESS>
            <STREET_NUM>25</STREET_NUM>
            <STREET_ADDRESS>ELM ST</STREET_ADDRESS>
            <STREET_PREFIX/>
            <STREET_NAME>ELM</STREET_NAME>
            <STREET_TYPE>ST</STREET_TYPE>
            <STREET_SUFFIX/>
        </PROPERTY_ADDRESS>
    </PROPERTY>
</RESPONSE>

У меня есть структура класса, которая соответствует:

[DataContract(Name="RESPONSE", Namespace="")]
public class Response
{
    [DataMember(Name="KEY")]
    public string Key { get; set; }

    [DataMember(Name = "PROPERTY")]
    public Property Property { get; set; }
}

[DataContract(Name="PROPERTY", Namespace="")]
public class Property
{
    [DataMember(Name="PROPERTY_ADDRESS")]
    public PropertyAddress Address { get; set; }
}


[DataContract(Name="PROPERTY_ADDRESS", Namespace="")]
public class PropertyAddress
{
    [DataMember(Name="STREET_NUM")]
    public string StreetNumber { get; set; }

    [DataMember(Name = "STREET_ADDRESS")]
    public string StreetAddress { get; set; }

    [DataMember(Name = "STREET_PREFIX")]
    public string StreetPrefix { get; set; }

    [DataMember(Name = "STREET_NAME")]
    public string StreetName { get; set; }

    [DataMember(Name = "STREET_TYPE")]
    public string StreetType { get; set; }

    [DataMember(Name = "STREET_SUFFIX")]
    public string StreetSuffix { get; set; }
}

Мой код десериализации выглядит следующим образом:

[Test]
public void TestMapping()
{
    var serializer = new DataContractSerializer(typeof(Response));

    Response response = null;

    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(XmlData)))
    {
        response = (Response)serializer.ReadObject(ms);
    }

    //This works
    Assert.AreEqual("12345", response.Key);

    //This works
    Assert.AreEqual("25", response.Property.Address.StreetNumber);

    //This FAILS. StreetAddress is null
    Assert.AreEqual("ELM ST", response.Property.Address.StreetAddress);
}

В жизни я не могу понять, почему StreetAddress терпит неудачу. Это должно быть что-то простое, что мне не хватает.

4b9b3361

Ответ 1

DataContractSerializer ожидает, что что-то будет в алфавитном порядке. Вы должны добавить Order к своим членам данных, чтобы это правильно работало.

[DataContract(Name = "PROPERTY_ADDRESS", Namespace = "")]
public class PropertyAddress
{
    [DataMember(Name = "STREET_NUM", Order=0)]
    public string StreetNumber { get; set; }

    [DataMember(Name = "STREET_ADDRESS", Order=1)]
    public string StreetAddress { get; set; }

    [DataMember(Name = "STREET_PREFIX", Order=2)]
    public string StreetPrefix { get; set; }

    [DataMember(Name = "STREET_NAME", Order=3)]
    public string StreetName { get; set; }

    [DataMember(Name = "STREET_TYPE", Order=4)]
    public string StreetType { get; set; }

    [DataMember(Name = "STREET_SUFFIX",Order=5)]
    public string StreetSuffix { get; set; }
}

Ответ 2

Вам нужно увеличить контракт на данные с порядком элементов, потому что DataContractSerializer ожидает, что элементы будут отсортированы по алфавиту по умолчанию. Это не относится к вашему XML.

Здесь код:

[DataContract(Name = "PROPERTY_ADDRESS", Namespace = "")]
public class PropertyAddress
{
    [DataMember(Name = "STREET_NUM", Order=1)]
    public string StreetNumber { get; set; }

    [DataMember(Name = "STREET_ADDRESS", Order=2)]
    public string StreetAddress { get; set; }

    [DataMember(Name = "STREET_PREFIX", Order=3)]
    public string StreetPrefix { get; set; }

    [DataMember(Name = "STREET_NAME", Order=4)]
    public string StreetName { get; set; }

    [DataMember(Name = "STREET_TYPE", Order=5)]
    public string StreetType { get; set; }

    [DataMember(Name = "STREET_SUFFIX", Order=6)]
    public string StreetSuffix { get; set; }
}