4

我正在使用调用 Web 服务并在客户端上使用 WCF 生成的服务引用。我已将从测试服务接收到的 XML 响应保存到磁盘(没有 SOAP 信封和正文标记)我想从磁盘加载它们并从中创建对象。让我们从我的网络服务中采用以下方法:

SomeMethodResponse SomeMethod(SomeMethodRequest req)

我手动(通过 SOAP UI)将响应保存到磁盘到文件,示例响应:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse>

然后我尝试使用以下方法从文件中反序列化对象:

DataContractSerializer dcs = 
  new DataContractSerializer(typeof(SomeMethodResponse))

这失败了——序列化程序抱怨错误,它期待命名空间“ http://schemas.datacontract.org/2004/07 ”中的元素,但在“ http://myNamespace ”中找到元素。

问题:为什么不DataContractSerializer使用在 SomeMethodResponseType 上声明的命名空间XmlTypeAttribute(Namespace="http://myNamespace")

我可以通过向DataContractSerializer构造函数显式提供命名空间和根元素来解决这个问题。但随后它失败,消息类似于:

X 行位置 Y(XML 文档的最后一行)出错。'EndElement' 'SomeMethodResponse
来自命名空间'httpmyNapespace' 不是预期的。期待元素“someNameField”。

SomeName是 Web 服务正在使用的 XSD 中的一个元素。它也是SomeMethodResponse类型的一个属性,由名为 的私有字段支持someNameField。看起来DataContractSerializer除了属性之外,它还试图反序列化这些字段。

如何使从磁盘保存的 XML 脱轨并取回 SomeMethod 返回的相同类型的对象?

谢谢, 马特拉

4

2 回答 2

5

您的 XML 响应显然有一个 XML 命名空间:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse xmlns="http://myNamespace">

所以为了正确读取和反序列化这个,你需要告诉你的 DataContractSerializer 这个命名空间:

DataContractSerializer dcs = 
    new DataContractSerializer(typeof(SomeMethodResponse),
                               "SomeMethodResponse", "http://myNamespace")

通过在构造函数中指定这个默认的 XML 命名空间,它现在应该能够读取和反序列化这个 XML。

你得到的另一个错误:

X 行位置 Y(XML 文档的最后一行)出错。'EndElement' 'SomeMethodResponse 来自命名空间'httpmyNapespace' 不是预期的。期待元素“someNameField”。

是由非常不寻常且从未见过的事实引起的,即您的最终元素上有一个命名空间......

</SomeMethodResponse xmlns="http://myNamespace">

只需删除多余的不必要的命名空间,就可以了!

</SomeMethodResponse>
于 2010-03-18T06:05:20.853 回答
5

让我回答我自己的问题:第二个错误消息的原因实际上是 svcUtil 默默地选择使用XmlSerializerinsted of DataContractSerializer。我通过阅读以下帮助找到了这一点XmlTypeAttribute- MSDn 状态控制当属性目标由 XmlSerializer 序列化时生成的 XML 模式。;-) 所以我们又回到了旧时代,XmlSerializer

于 2010-03-18T07:41:16.263 回答