By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,611 Members | 1,629 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,611 IT Pros & Developers. It's quick & easy.

XmlSerializer bug for xs:choice?

P: n/a
(This is using .net version 2.0.50727 and system.xml 2.0.50727.42)

I am getting an error when serializing using classes generated by xsd.exe.
The error is of the type "The Type <typewas not expected. Use the
XmlInclude or SoapInclude etc"
This error is appearing sprodically, with no obvious pattern. When it
occurs, it happens every time we run the code, however changes to our code in
creating the objects before they are serialized sometimes make it go away
(again, no obvious pattern).
Also, we have taken the same code and data, compiled it on two machines
built from the same image (but probably a bit dirty as they have been used by
devs for a while, although no significant changes in software versions, .net
framework, vs etc), and one has worked and one hasn't.
A bit more depth>>>>>>

The schema contains a choice, of which one of the choices is an element with
no child elements or attributes.
E.g.

<xs:element name="Animal">
<xs:complexType>
<xs:choice>
<xs:element name="Dog">
<xs:complexType>
<xs:attribute name="Name" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Cow">
<xs:complexType>
<xs:attribute name="Name" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Pig">
</xs:element>
<xs:element name="Sheep">
<xs:complexType>
<xs:attribute name="Name" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
This has generated the following class (along with lots of others from the
farmyard schema ;) ) using xsd.exe

public partial class Animal
{

private object itemField;

[System.Xml.Serialization.XmlElementAttribute("Pig" , typeof(object))]
[System.Xml.Serialization.XmlElementAttribute("Dog" , typeof(AnimalDog))]
[System.Xml.Serialization.XmlElementAttribute("Cow" , typeof(AnimalCow))]
[System.Xml.Serialization.XmlElementAttribute("Shee p", typeof(AnimalSheep))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}

Interestingly, the generated code shown above is slightly different for this
case (choice which contains only 1 element with no child elements or
attributes) than for another choice in the schema which contains more than 1
element that has no child elements or attributes. In that scenario an extra
field is generated called ItemChoiceType and there is an extra attribute on
Item (XmlChoiceIdentifierAttribute). ??I believe this is significant as the
runtime generated serializer code handles it differently??

I have looked at the runtime generated serializer code at the offending
method...
void Write11_Animal(some params incl. global::FarmyardNamespace.Animal o)
{
...

WriteStartElement(..);

...

if (o.@Item is global::FarmyardNamespace.Dog)
{
Write10_Item(@"Dog", ... some more params);
}
else if (o.@Item is global::System.Object)
{
Write2_Object(@"Pig", ... some more params);
}
else if (o.@Item is global:FarmyardNamespace.Cow)
{
Write9_Item(@"Cow", ... some more params);
}
else if (o.@Item is global:FarmyardNamespace.Sheep)
{
Write8_Item(@"Sheep", ... some more params);
}

...

WriteEndElement(...);
}

As you can see, if the o parameter is a Cow, it will still get caught by the
"o@Item is global::System.Object" clause, and then doesn't get caught by any
of the clauses in the big if statement in Write2_Object method (not shown),
and eventually causes it to fall over in WriteTypedPrimitive method.

I'm not sure what causes the runtime generated serializer code to determine
the order of the if statement shown above, but could explain the problems
with it working at different points in time and on different machines.
There is a very simple workaround to this... add a dummy attribute to the
single element with no child elements or attributes.
In our situation, although it is a complete hack, it is actually a viable
thing to do. However, if there is a "nice" way to fix this, then please could
somebody tell me, or is it a real bug?

----------------
This post is a suggestion for Microsoft, and Microsoft responds to the
suggestions with the most votes. To vote for this suggestion, click the "I
Agree" button in the message pane. If you do not see the button, follow this
link to open the suggestion in the Microsoft Web-based Newsreader and then
click "I Agree" in the message pane.

http://www.microsoft.com/communities...lic.dotnet.xml
Feb 1 '07 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.