我有一个相当复杂的WSDL,我将其添加到Visual Studio中作为服务引用。我遇到的问题是,自动生成的客户端代码不能正确地处理抽象类型(并且忽略了替代该抽象类型的所有类型)。我不想发布整个WSDL,但这里有一个片段:
<complexType name="AddTextFields">
<complexContent>
<extension base="ti:TransformationInstructions">
<sequence>
<element name="textFieldList"
type="atf:TextFieldList" />
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="TextFieldList">
<sequence>
<element ref="atf:TextFieldBase"
maxOccurs="unbounded" />
</sequence>
</complexType>
<element name="TextFieldBase" abstract="true"/>
<element name="textField" substitutionGroup="atf:TextFieldBase">
<complexType>
<sequence>
...
</sequence>
</complexType>
</element>
<element name="checkBox" substitutionGroup="atf:TextFieldBase">
<complexType>
<sequence>
...
</sequence>
</complexType>
</element>
所以你可以看到这里TextFieldList可以有无限的TextFieldBase类型的元素(它可以是textField, checkBox和其他一些我省略)。然而,在创建WSDL客户端时,.NET似乎并不关心这一点,并生成像这样的textFieldList:
[System.Xml.Serialization.XmlArrayAttribute(Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("TextFieldBase", IsNullable=false)]
public object[] textFieldList {
get {
return this.textFieldListField;
}
set {
this.textFieldListField = value;
this.RaisePropertyChanged("textFieldList");
}
}
我在WSDL中有一些其他正确工作的抽象类型,在尝试比较它们时,我发现如果我从TextFieldList定义中删除maxOccurs="unbounded"属性,那么。net将正确生成插入抽象类型的类型。不幸的是,我们需要能够有1个或更多的textFieldList元素,这样将无法工作。
这只是。net中的一个bug吗?或者是否存在一些不需要彻底更改WSDL就可以工作的解决方案?
我考虑的一个解决方案是将实现更改为一个选择,而不是使用abstract:
<complexType name="TextFieldList">
<choice maxOccurs="unbounded">
<element ref="atf:textField" />
<element ref="atf:checkBox" />
<element ref="atf:radioButtonGroup" />
<element ref="atf:listBox" />
<element ref="atf:comboBox" />
</choice>
</complexType>
移动maxOccurs属性'修复'这个问题。
<complexType name="TextFieldList">
<sequence maxOccurs="unbounded">
<element ref="atf:TextFieldBase" />
</sequence>
</complexType>