The “Add Web Reference” Visual tool generates bad classes (from WSDL schema)
for ComplexType containing only one element (wsdl.exe and wseWsdl3.exe tools
have the same problem) : if a ComplexType A contains only one element, the
tool don’t generate a class for the ComplexType A. It generates a class only
for the element type (B) included in this ComplexType (if this type contains
more than one element...). For types in WSDL schéma including a ComplexType A
element, the generated classes for these types contains a B element (and not
a A element containing a B element).
For example, for this part of WSDL schema:
<xsd:complexType name="ClassInst">
<xsd:sequence>
<xsd:element name="ClassName" type="ClassName"/>
<xsd:element name="Inst" type="Instance" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="StructuredEntitySpec">
<xsd:sequence>
<xsd:element name="EntityClassInst" type="ClassInst" maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="EntitySpec">
<xsd:sequence>
<xsd:element name="Structured" type="StructuredEntitySpec" minOccurs="0"/>
<xsd:element name="Syno" type="xsd:string" minOccurs="0"/>
<xsd:element name="Natural" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
Will generate the following code:
public partial class ClassInst {
private string classNameField;
private Instance instField;
....
}
public partial class EntitySpec {
private ClassInst[] structuredField;
private string synoField;
private string naturalField;
…
}
The EntitySpec class doesn’t contain a StructuredEntitySpec element but a
ClassInst[] element (declared in the StructuredEntitySpec XML element).
This error cause deserialization problems. when the Web Service client
receive the SOAP message :
....
<entitySpec>
<structured>
<EntityClassInst>
<ClassName>...</ClassName>
<Inst>...<Inst>
</ EntityClassInst>
</structured>
<syno></syno>
<natural></natural>
</entitySpec>
....
the entitySpec XML element is not conform to classes structure : the
<EntityClassInst> element is not declared in classes so deserialization
failed (the <EntityClassInst> is unknown).
Deserializer needs to have this XML element :
....
<entitySpec>
<structured>
<ClassName>...</ClassName>
<Inst>...<Inst>
</structured>
<syno></syno>
<natural></natural>
</entitySpec>
....
To prevent from this bug, in all ComplexType containing only one element, we
had to add a new optional element (unused) :
<xsd:complexType name="ClassInst">
<xsd:sequence>
<xsd:element name="ClassName" type="ClassName"/>
<xsd:element name="Inst" type="Instance" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="StructuredEntitySpec">
<xsd:sequence>
<xsd:element minOccurs="0" name="WorkArounddotNetBug" type="xsd:integer"/>
<xsd:element name="EntityClassInst" type="ClassInst" maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="EntitySpec">
<xsd:sequence>
<xsd:element name="Structured" type="StructuredEntitySpec" minOccurs="0"/>
<xsd:element name="Syno" type="xsd:string" minOccurs="0"/>
<xsd:element name="Natural" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
Generated classes for these XML types :
public partial class ClassInst {
private string classNameField;
private Instance instField;
....
}
public partial class StructuredEntitySpec {
private string workArounddotNetBugField;
private ClassInst[] entityClassInstField;
....
}
public partial class EntitySpec {
private StructuredEntitySpec structuredField;
private string synoField;
private string naturalField;
....
}
Generated classes are now conform to XML document.