2013-11-14 2 views
10

У меня проблема с DataContractSerializer. Я использую его для создания экземпляров класса из XML, возвращаемого веб-службой ASP.NET. Но на самом деле источник данных здесь не важен. Чтобы облегчить отладку всего дела, я создал простой тестовый проект с сериализацией, и проблема все еще возникает.Некоторые свойства не десериализуются с использованием DataContractSerializer

Вот мой XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<GetTestURL p1:type="MyApp.GetTestUrlInfo" xmlns:p1="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices"> 
    <TestURL>http://bing.com</TestURL> 
    <UserCount p1:type="Edm.Int32">1</UserCount> 
    <InitialCount p1:type="Edm.Int32">1</InitialCount> 
    <AverageExecutionTime p1:type="Edm.Int32">43</AverageExecutionTime> 
</GetTestURL> 

Класс Я пытаюсь десериализации XML в:

[DataContract(Name = "GetTestURL", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")] 
public class TestInfo 
{ 
    [DataMember(Name = "TestURL")] 
    public Uri TestUri { get; private set; } 

    [DataMember(Name = "UserCount")] 
    public int UserCount { get; private set; } 

    [DataMember(Name = "InitialCount")] 
    public int InitialCount { get; private set; } 

    [DataMember(Name = "AverageExecutionTime")] 
    public int AverageExecutionTime { get; private set; } 
} 

И мой сериализации вспомогательный класс:

public static class SerializationHelper<T> 
{ 
    private static DataContractSerializer _serializer = new DataContractSerializer(typeof(T)); 

    public static T Deserialize(Stream source) 
    { 
     return (T)_serializer.ReadObject(source); 
    } 
} 

Код испытания:

// Test program 
public static void Main() 
{ 
    TestInfo info = null; 
    using (var stream = File.Open("Input.xml", FileMode.Open, FileAccess.Read)) 
    { 
     info = SerializationHelper<TestInfo>.Deserialize(stream); 
    } 
} 

После установки brakepoint в конце метода я вижу следующее:

enter image description here

Как вы можете видеть, как AverageExecutionTime и InitialCount не десериализации и имеют int значения по умолчанию. Они должны установить значение 43 и 1, поскольку эти значения указаны в XML.

Это еще более странно для меня, что собственность UserCount выполнена правильно, но на самом деле она не отличается от двух, которая вообще не работает. Единственное отличие - это имя элемента.

+0

Возможные дублируют http://stackoverflow.com/questions/15413468/deserializing-xml-with-datacontractserializer?rq=1 –

ответ

10

Мне удалось заставить его работать, обновив контракт с данными. Что-то делать с порядком. Когда я сделал Uri требуемым свойством, он выбросил исключение, так что это может быть связано с порядком загрузки.

[DataContract(Name = "GetTestURL", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")] 
    public class TestInfo 
    { 
     public TestInfo() { } 
     public TestInfo(Uri uri, int userCount, int initialCount, int averageExecutionTime) 
     { 
      TestUri = uri; 
      UserCount = userCount; 
      InitialCount = initialCount; 
      AverageExecutionTime = averageExecutionTime; 
     } 
     [DataMember(Name = "TestURL", IsRequired=true, Order=1)] 
     public Uri TestUri { get; private set; } 

     [DataMember(Name = "UserCount", IsRequired=true, Order=2)] 
     public int UserCount { get; private set; } 

     [DataMember(Name = "InitialCount", IsRequired=true, Order=3)] 
     public int InitialCount { get; private set; } 

     [DataMember(Name = "AverageExecutionTime", IsRequired=true, Order=4)] 
     public int AverageExecutionTime { get; private set; } 
    } 
+0

Есть ли у вас какие-либо идеи, почему это не работает без 'Order' /' IsRequired' ? – MarcinJuraszek

+1

@MarcinJuraszek Я сделал два теста, Удалил все свойства IsRequired и Order и изменил входной XML-адрес в алфавитном порядке. * Сработало * Убрано IsRequired и сохранили заказ как есть. * работал * Кажется, что сериализатор использует ваш класс для чтения документа. Если вы не укажете порядок, он не знает, как искать элементы в правильной последовательности. По умолчанию используемая последовательность является алфавитной. –

+4

@MarcinJuraszek «DataContractSerializer» использует/ожидает строгий порядок элементов в XML в документации [здесь] (http://msdn.microsoft.com/en-us/library/ms729813.aspx). Если ваши XML-элементы не будут отображаться в порядке по умолчанию для правил, вам нужно указать порядок в атрибуте '[DataMember]', как показано в ответе Патрика. –

Смежные вопросы