Visual Studio 用于生成 Web 服务代理的工具 wsdl.exe 中似乎存在一个已知错误。对于某些 XSD 架构,该工具将生成无法从 XML 反序列化的类。
就我而言,这是不可接受的,但我不知道如何解决它。
我将详细描述我的情况,希望有人能够帮助我。
Schema
<!-- return type from the service operation -->
<xs:complexType name="listAssetsQueryResults">
<xs:sequence>
<xs:element name="assets" type="tns:asset" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- a sequence of attributes -->
<xs:complexType name="asset">
<xs:sequence>
<xs:element name="attributes" type="tns:multiValuedAttribute" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="multiValuedAttribute">
<!-- not relevant-->
</xs:complexType>
来自 Web 服务的 XML 响应
根据此模式的典型响应如下所示:
<assets-query-result>
<assets>
<attributes>
<name>Keywords</name>
<values>Desert</values>
</attributes>
<attributes>
<name>Filename</name>
<values>Desert.jpg</values>
</attributes>
</assets>
<assets>...</assets>
<assets>...</assets>
</assets-query-result>
在代码中使用类型
我本来希望能够使用这样的 CLR 类型:
result.assets[0].attributes[0].name
相反,生成的结果类型如下所示:
[SerializableAttribute()]
public partial class listAssetsQueryResults {
private multiValuedAttribute[][] assetsField;
[XmlArrayAttribute(Form=XmlSchemaForm.Unqualified, IsNullable=true)]
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets {
get { return this.assetsField; }
set { this.assetsField = value; }
}
}
这甚至不允许生成序列化程序集!
无法转换类型
Portfolio.WebService.multiValuedAttribute
到 Portfolio.WebService.multiValuedAttribute[]
修复它
1 - 更改属性和字段的类型
现在,我在网上找到的修复方法之一就是从生成的属性类型中删除一对括号:
// No longer a jagged array, but this doesn't deserialize all data
public multiValuedAttribute[] assets;
这允许构建序列化程序集,并且它运行时没有异常,除了它没有正确序列化数据,它“跳过”资产列表并反序列化第一个资产的属性assets
元素。所以这根本不是修复,因为通过此修复我无法使用数据。对于 700 多种资产,它提供result.assets
等于multiValuedAttribute[2]
(这两个元素是第一个资产的名称和关键字属性)。
2 - 指定 XML 元素的类型
我尝试的第二件事是给解串器不同的指令:
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute[]), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets { ... }
所以现在我告诉它序列中的每个元素都是类型multiValuedAttribute[]
。这是错误的,因为它仍在寻找attributes
元素,其类型为multiValuedAttribute
(单个,不是数组)。然而它确实运行了,但现在result.assets
等于multiValuedAttribute[2][0]
我仍然无法获取数据。
下一步是什么?
我不知道,这就是我写这篇文章的原因。我无法接受 .NET 无法使用此 Web 服务,因为它必须这样做。