Pages

Saturday, October 6, 2012

SvcUtils generates incorect code with multidimensional arrays

There may be situation when you need create .NET client for some webservice. The easiest way is to get the WSDL file and generates the clients using SvcUtils.exe tool. In most cases it everything goes fine and you can quickly finish your work. But there is a special case when the SvcUtils and its predecessor - wsdl.exe will fail.

Lets assume that schema contains such element:
<xs:element name="Description" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Text" minOccurs="0" maxOccurs="unbounded" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
SvcUtils tries to be smart and generates:
private string[][] text;

[System.Xml.Serialization.XmlArrayAttribute(Order = 1)]
[System.Xml.Serialization.XmlArrayItemAttribute("Text", typeof(string), IsNullable = false)]
public string[][] Description {
    get {
        return this.text;
    }
    set {
        this.text = value;
    }
}
OK, nearly great. But when you try to use this code you experience the cast exception as there won't be possibility of casting string to string[]. The typeof parameter of XmlArrayItemAttribute is wrong! The attribute is an array of arrays, then the correct type is string[]!

Quick changes is enough to make the code work properly. But if you are the author of the service and wont to your user to avoid doing this there is one simple solution - just move the occurrences definition from Text element and place it in sequence node, that is:
<xs:element name="Describtion" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="Text" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
</xs:element>
After this SvcUtils will generate separate class for Description element and everything will work out of the box.

0 komentarze:

Post a Comment