我有一个相当复杂的 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 中的一个错误吗?或者是否有一些解决方法可以在不彻底改变 WSDL 的情况下工作?
我考虑的一种解决方法是将实现更改为一种选择,而不是使用抽象:
<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>