DataContractSerializer和反序列化Web服务响应类型

时间:2010-03-18 00:09:10

标签: c# wcf web-services datacontractserializer

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

SomeMethodResponse SomeMethod(SomeMethodRequest req)

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

<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(XMLdocument的最后一行)出错。 'EndElement''SomeMethodResponse
来自命名空间'httpmyNapespace'不是预期的。 期待元素'someNameField'。

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

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

谢谢,   马特拉

2 个答案:

答案 0 :(得分: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(XMLdocument的最后一行)出错。 “结束元素”   不期望来自命名空间'httpmyNapespace'的SomeMethodResponse。   期待元素'someNameField'。

是由非常不寻常且前所未见的事实引起的,你的end元素上有一个命名空间........

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

只需删除那个额外不必要的命名空间,你应该没问题!

</SomeMethodResponse>

答案 1 :(得分:5)

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