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:complexTyp e name="ClassInst ">
<xsd:sequence >
<xsd:element name="ClassName " type="ClassName "/>
<xsd:element name="Inst" type="Instance" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType >
<xsd:complexTyp e name="Structure dEntitySpec">
<xsd:sequence >
<xsd:element name="EntityCla ssInst" type="ClassInst " maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType >
<xsd:complexTyp e name="EntitySpe c">
<xsd:sequence >
<xsd:element name="Structure d" type="Structure dEntitySpec" minOccurs="0"/>
<xsd:element name="Syno" type="xsd:strin g" minOccurs="0"/>
<xsd:element name="Natural" type="xsd:strin g" 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 StructuredEntit ySpec element but a
ClassInst[] element (declared in the StructuredEntit ySpec XML element).
This error cause deserialization problems. when the Web Service client
receive the SOAP message :
....
<entitySpec>
<structured>
<EntityClassIns t>
<ClassName>.. .</ClassName>
<Inst>...<Ins t>
</ EntityClassInst >
</structured>
<syno></syno>
<natural></natural>
</entitySpec>
....
the entitySpec XML element is not conform to classes structure : the
<EntityClassIns t> element is not declared in classes so deserialization
failed (the <EntityClassIns t> is unknown).
Deserializer needs to have this XML element :
....
<entitySpec>
<structured>
<ClassName>.. .</ClassName>
<Inst>...<Ins t>
</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:complexTyp e name="ClassInst ">
<xsd:sequence >
<xsd:element name="ClassName " type="ClassName "/>
<xsd:element name="Inst" type="Instance" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType >
<xsd:complexTyp e name="Structure dEntitySpec">
<xsd:sequence >
<xsd:element minOccurs="0" name="WorkAroun ddotNetBug" type="xsd:integ er"/>
<xsd:element name="EntityCla ssInst" type="ClassInst " maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType >
<xsd:complexTyp e name="EntitySpe c">
<xsd:sequence >
<xsd:element name="Structure d" type="Structure dEntitySpec" minOccurs="0"/>
<xsd:element name="Syno" type="xsd:strin g" minOccurs="0"/>
<xsd:element name="Natural" type="xsd:strin g" 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 StructuredEntit ySpec {
private string workArounddotNe tBugField;
private ClassInst[] entityClassInst Field;
....
}
public partial class EntitySpec {
private StructuredEntit ySpec structuredField ;
private string synoField;
private string naturalField;
....
}
Generated classes are now conform to XML document.