2009-10-30 12 views
11

Moja SomeClassDataContractSerializer nie prawidłowo deserializowania wartości dla metod w obiekcie brakuje

[Serializable] 
[DataContract(Namespace = "")] 
public class SomeClass 
{ 
    [DataMember] 
    public string FirstName 
    { 
     get; set; 
    } 

    [DataMember] 
    public string LastName 
    { 
     get; set; 
    } 

    [DataMember] 
    private IDictionary<long, string> customValues; 
    public IDictionary<long, string> CustomValues 
    { 
     get { return customValues; } 
     set { customValues = value; } 
    } 
} 

Moje XML File:

<?xml version="1.0" encoding="UTF-8"?> 
<SomeClass> 
<FirstName>John</FirstName> 
<LastName>Smith</LastName> 
<CustomValues> 
    <Value1>One</Value1> 
    <Value2>Two</Value2> 
</CustomValues > 
</SomeClass> 

Ale mój problem jest dla danej klasy, otrzymuję tylko niektóre dane dla moich metod, gdy deserializuję.

var xmlRoot = XElement.Load(new StreamReader(
        filterContext.HttpContext.Request.InputStream, 
        filterContext.HttpContext.Request.ContentEncoding)); 
XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlRoot.CreateReader()); 
DataContractSerializer ser = new DataContractSerializer(typeof(SomeClass)); 
//Deserialize the data and read it from the instance. 
SomeClass someClass = (SomeClass)ser.ReadObject(reader, true); 

Kiedy więc sprawdzić „SomeClass”, imię będzie miał wartość John Ale Nazwisko będzie null.

Tajemnica to sposób uzyskania niektórych danych, a nie wszystkich danych dla klasy. Tak DataContractSerializer nie pobiera wszystkich danych z xml podczas deserializacji.

Czy robię coś nie tak.

Każda pomoc jest doceniana. Z góry dziękuję.

Daj mi znać, jeśli ktoś ma ten sam problem czy ktoś ma rozwiązanie

+1

nie powinien DataMember atr mieć na własność publiczną, a nie na prywatnym jednego? – Dani

Odpowiedz

16

Dobrze znalazłem własną odbieranie po odtworzeniu go dużo wokół .... to musi być w alpahbetical kolejności. więc jeśli klasa ma

[Serializable] 
[DataContract(Namespace = "")]  
public class SomeClass 
{ 
    [DataMember] 
    public string FirstName 
    { 
     get; set; 
    } 

    [DataMember] 
    public string LastName 
    { 
     get; set; 
    } 

    [DataMember] 
    private IDictionary<long, string> customValues; 
    public IDictionary<long, string> CustomValues 
    { 
     get { return customValues; } 
     set { customValues = value; } 
    } 
} 

xml następnie należy określić alfabetycznie.

<?xml version="1.0" encoding="UTF-8"?> 
<SomeClass> 
<CustomValues> 
    <Value1>One</Value1> 
    <Value2>Two</Value2> 
</CustomValues > 
<FirstName>John</FirstName> 
<LastName>Smith</LastName> 
</SomeClass> 

Cóż, dlaczego h ... musi być alfabetycznie?

+1

"Wydajność" widocznie. Szaleństwo! –

+0

Dziękujemy za opublikowanie tej niesamowitej wiedzy. Uderzyłem tym samym kodem, który "prawie" działa godzinami. Szybka zmiana schematu i działa przyjemnie. Zastanawiasz się, dlaczego nie jest to lepiej udokumentowane w produkcie. +1 –

+1

Wow, ja też zmarnowałem godziny, próbując znaleźć rozwiązanie tego problemu. Powoduje to poważne problemy, jeśli usługa internetowa zwraca elementy XML w innej kolejności niż specyfikacja WSDL - w tym przypadku serwer proxy wygenerowany przez SvcUtil będzie miał błędną kolejność i deserialization po cichu zawiedzie. – Oenotria

13

Do tego służy atrybut Order; jeśli nie masz kontroli nad formatem XML, który deserializujesz, jest to jedyne obejście, o którym wiem.

W pierwszym przykładzie, że byłoby

[Serializable] 
[DataContract(Namespace = "")] 
public class SomeClass 
{ 
    [DataMember(Order = 0)] 
    public string FirstName 
    { 
     get; set; 
    } 

    [DataMember(Order = 1)] 
    public string LastName 
    { 
     get; set; 
    } 

    [DataMember(Order = 2)] 
    private IDictionary customValues; 
    public IDictionary CustomValues 
    { 
     get { return customValues; } 
     set { customValues = value; } 
    } 
} 
Powiązane problemy