DataContract deserialization fails due to incorrect ordering of XML nodes
Asked Answered
H

2

8

I am baffled with the behavior of the DataContractSerializer. Our configuration is XML based. XML is used as source for DataContractSerializer.ReadObject method. Recently I have encountered a problem when some properties of deserialized object were not set. I have tracked the changes and discovered that those properties were added into XML manually. Which is OK in my opinion. Apparently it was not OK in DataContractSerializer's opinion because it appears it expects XML nodes to be ordered alphabetically. Really?! Deserialization seems like really straightforward thing - read XML sequentially, parse node name, set corresponding property. What's the purpose of ordering?

Is there a workaround? Maybe some sort of settings for DataContractSerializer?

Halsted answered 20/3, 2012 at 22:46 Comment(0)
B
3

I encountered this problem recently. To work around it, I used the XmlSerializer and removed the explicit ordering from the XmlElement attributes:

set proxy_tool="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SvcUtil.exe" /nologo /t:code /ser:XmlSerializer /UseSerializerForFaults
set sed_tool="$(ProjectDir)sed.exe" -r -i "s/,?[[:space:]]*Order=[[:digit:]]+//"

%proxy_tool%  /o:"Proxy1.cs" /n:*,Namespaces.Name1 "Proxy1.wsdl"
%sed_tool% "Proxy1.cs"

%proxy_tool%  /o:"Proxy2.cs" /n:*,Namespaces.Name2 "Proxy2.wsdl"
%sed_tool% "Proxy2.cs"

...

There's some more information on my blog post.

If you want to know why the order matters, it's because a sequence in XSD has a defined order, and the web service contracts are defined with XSD.

From the specification:

The consequence of this definition is that any element appearing in an instance whose type is declared to be USAddress (e.g. shipTo in po.xml) must consist of five elements and one attribute. These elements must be called name, street, city, state and zip as specified by the values of the declarations' name attributes, and the elements must appear in the same sequence (order) in which they are declared.

Bought answered 21/3, 2012 at 4:59 Comment(3)
Wow... That seems a tad too complicated. But thanks for the answer. I ended up trying DataContractSerializer and it worked for me better.Halsted
Is there no way one can use "xs:all" definition in DataContract? So then order doesn't matter?Syllepsis
@Syllepsis Perhaps if you have control over the WSDLsBought
P
3

You can use the Order member of DataMemberAttribute to help with this, but in most cases: XML is order-specific (for elements, not attributes) - so it isn't specifically wrong.

That said: if you want fine control over XML serialization, DataContractSerializer is a poor choice XmlSerializer offers more control - and is less fussy re order iirc.

Pottery answered 20/3, 2012 at 23:4 Comment(1)
I see your point. I guess I am lazy in this case because the same object is used as a parameter to WCF based service so it's kind of convenient not to think about two ways of serialization.Halsted
B
3

I encountered this problem recently. To work around it, I used the XmlSerializer and removed the explicit ordering from the XmlElement attributes:

set proxy_tool="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SvcUtil.exe" /nologo /t:code /ser:XmlSerializer /UseSerializerForFaults
set sed_tool="$(ProjectDir)sed.exe" -r -i "s/,?[[:space:]]*Order=[[:digit:]]+//"

%proxy_tool%  /o:"Proxy1.cs" /n:*,Namespaces.Name1 "Proxy1.wsdl"
%sed_tool% "Proxy1.cs"

%proxy_tool%  /o:"Proxy2.cs" /n:*,Namespaces.Name2 "Proxy2.wsdl"
%sed_tool% "Proxy2.cs"

...

There's some more information on my blog post.

If you want to know why the order matters, it's because a sequence in XSD has a defined order, and the web service contracts are defined with XSD.

From the specification:

The consequence of this definition is that any element appearing in an instance whose type is declared to be USAddress (e.g. shipTo in po.xml) must consist of five elements and one attribute. These elements must be called name, street, city, state and zip as specified by the values of the declarations' name attributes, and the elements must appear in the same sequence (order) in which they are declared.

Bought answered 21/3, 2012 at 4:59 Comment(3)
Wow... That seems a tad too complicated. But thanks for the answer. I ended up trying DataContractSerializer and it worked for me better.Halsted
Is there no way one can use "xs:all" definition in DataContract? So then order doesn't matter?Syllepsis
@Syllepsis Perhaps if you have control over the WSDLsBought

© 2022 - 2024 — McMap. All rights reserved.