2013-11-14 14 views
10

Mam problem z DataContractSerializer. Używam go do tworzenia instancji klas z XML zwracanych przez ASP.NET Web Service. Ale w rzeczywistości źródło danych nie jest tutaj ważne. Aby ułatwić debugowanie całej sprawy, stworzyłem prosty projekt testowy z serializacją i problem nadal występuje.Niektóre właściwości nie są deserializowane przy użyciu DataContractSerializer

Tu jest mój 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> 

Klasa Usiłuję deserializować XML do:

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

A moja serializacji klasy pomocnika: Kod

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:

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

Po ustawieniu brakepoint na końcu metody widzę następujące:

enter image description here

Jak widać, zarówno AverageExecutionTime i InitialCount nie rozszeregować i mają int wartość domyślną. Powinny ustawić na 43 i 1, ponieważ te wartości są w formacie XML.

Jest mi jeszcze dziwniej, że własność UserCount jest wykonywana prawidłowo, ale w rzeczywistości nie różni się ona od tych dwóch, które w ogóle nie działają. Różni się tylko nazwa elementu.

+0

Możliwa powielać http://stackoverflow.com/questions/15413468/deserializing-xml-with-datacontractserializer?rq=1 –

Odpowiedz

10

Udało mi się go uruchomić, aktualizując umowę dotyczącą danych. Coś związanego z zamówieniem. Kiedy zrobiłem Uri żądaną właściwość, wyrzucił wyjątek, więc może to mieć coś wspólnego z zamówieniem ładunku.

[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

Czy masz jakiś pomysł, dlaczego to nie działa bez 'Order' /' IsRequired' ? – MarcinJuraszek

+1

@MarcinJuraszek Zrobiłem dwa testy, Usunięto wszystkie właściwości IsRequired i Order i zmieniono wejściowy xml, aby alfabetycznie uporządkować elementy. * pracował * Usunięto IsRequired i utrzymano zamówienie w niezmienionej formie. * przepracowany * Wygląda na to, że serializator używa twojej klasy do strumieniowego odczytywania dokumentu. Jeśli nie określisz kolejności, nie będzie szukał elementów we właściwej kolejności. Domyślnie używana sekwencja jest alfabetyczna. –

+4

@MarcinJuraszek 'DataContractSerializer' używa/oczekuje ścisłego uporządkowania elementów w XML na podstawie dokumentacji [tutaj] (http://msdn.microsoft.com/en-us/library/ms729813.aspx). Jeśli twoje elementy XML nie pojawią się w porządku domyślnym zgodnie z regułami, musisz podać kolejność w atrybucie '[DataMember]', jak pokazano w odpowiedzi Patricka. –

Powiązane problemy