.NET XmlSerializer – Unable to generate a temporary class

Ever get this error message when using Visual Studio-generated proxy objects to interact with a web service?

Unable to generate a temporary class

error CS0030: Cannot convert type ‘string[]’ to ‘string’

error CS0029: Cannot implicitly convert type ‘string’ to ‘string[]’

One of our clients recently ran into this problem. I was chosen to go undercover, deep into foreign, presumed hostile, .NET territory to troubleshoot. After downloading, installing, configuring Visual Studio and figuring out the changes since I last used it in 2005 I was able to reproduce the issue. After a bout of research and experimentation the problem was uncloaked.

It’s a bug in .NET’s XmlSerializer object. It incorrectly parses XSD elements containing exactly one element where that element’s maxOccurs is unbounded – without throwing any errors.

The issue is marked wontfix (reference: Daniel Roth, Microsoft Program Manager) and Microsoft’s suggested workaround is to change the XSD, adding an otherwise useless attribute declaration. See the example from http://connect.microsoft.com/VisualStudio/feedback/details/349967/xsd-exe-generates-code-with-the-wrong-type-in-an-xmlarrayitemattribute:


<xs:complexType name="Item">
<xs:sequence>
<xs:element name="item" type="xs:string" minOccurs='1'
maxOccurs='unbounded' />
</xs:sequence>
<!-- Prevents XmlSerializer from realizing this type contains
only one element -->
<xs:attribute name="OptionalAttribute" type="xs:string" />
</xs:complexType>

A rather ugly solution, to be sure. A couple things of note:

1. This is a runtime issue. If you have affected elements in your XSD and do not apply a fix, it won’t be a problem until their parent types are instantiated.

2. If you can’t modify the XSD (e.g. if you’re the consumer and the service provider can’t/won’t hack their schema to include pointless attributes for you), there’s an alternate but even uglier workaround. You have to generate the proxy objects and then manually replace all two-dimensional arrays with one-dimensional arrays. See http://satov.blogspot.com/2006/12/xsdexe-generated-classes-causing.html and http://stackoverflow.com/questions/812739/problem-deserializing-validated-xml-cant-convert-to-from-array for examples of folks who have chosen this route. Note that if the service schema ever changes, you would have to regenerate the proxy objects and do this manual search ‘n’ replace all over again.

In the end I was able to modify the service schema, as it’s unreasonable to expect all your .NET customers to go through this kind of rigamarole. I’m thankful wsdl2java does its job a bit better than XmlSerializer/xsd.exe.

Tags:

Leave a Comment