DataContractSerializer does not properly deserialize, values for methods in object are missing
Asked Answered
I

2

12

My SomeClass

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

My 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>

But my problem is for the class, i am only getting some of the data for my methods when i deserialize.

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

So when I check "someClass", FirstName will have the value john, But the LastName will be null.

Mystery is how can i get some of the data and not all of the data for the class. So DataContractSerializer is not pulling up all the data from xml when deserializing.

Am i doing something wrong.

Any help is appreciated. Thanks in advance.

Let me know if anyone has the same problem or any one has solution

Isotron answered 30/10, 2009 at 16:47 Comment(1)
shouldn't the DataMember attr be on the public property and not on the private one ?Ginni
I
17

Well i found my own answering after playing it a lot around....it has to be in an alpahbetical order. so if class has

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

then xml should be define alphabetically.

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

well why the h... it has to be in alphabetical?

Isotron answered 30/10, 2009 at 19:32 Comment(4)
Thank you for posting this amazing piece of knowledge. I have been headbanging the same bit of code that 'nearly' works for hours. Quick schema change and it works a treat. You've got to wonder why this isn't more clearly documented in the product. +1Isochronize
Wow, I've also just wasted hours trying to find the solution to this. This causes some serious issues if a web service returns XML elements in a different order to the WSDL spec - in this case the proxy generated by SvcUtil will have the wrong ordering and deserialisation silently fails.Polluted
@Polluted I just spent 2 hours with the same issue. This is unreal. Microsoft must be full of complete morons. They must be iterating an objects properties from a sorted list, and checking if the current XML node holds a child that corresponds to the property. They are doing it backwards. Iterate the XML nodes, and look up if a property corresponding to the property exists. This is disgusting. I'm so over jumping through hoops to satisfy Microsoft's serialization.Homerhomere
In PortableRest, we get past this issue by using XLinq to clean the XML and then sort the XML nodes in alphabetical order before passing it to the serializer. Here's how we use it: github.com/advancedrei/PortableRest/blob/master/src/…. If you have having to deal with web services, you can call them REST-fully with PortableRest and we'll do this automagically for you.Bertero
D
15

That’s what the Order attribute is for; if you don’t have control on the XML you deserialize, that’s the only workaround I know about.

In your first example that would be

[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; }
    }
}
Digestible answered 3/4, 2010 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.