我正在使用ksoap2向Android客户端发送此请求到我的WCF网络服务:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"><v:Header />
<v:Body>
<HelloComplex xmlns="http://tempuri.org/" id="o0" c:root="1">
<complex i:type="n0:SampleComplexType" xmlns:n0="http://tempuri.org/">
<Value i:type="d:string">Hello!</Value>
</complex>
</HelloComplex>
</v:Body>
</v:Envelope>
并收到这个:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
<faultstring xml:lang="pt-BR">
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:complex. The InnerException message was 'Error in line 1 position 363. Element 'http://tempuri.org/:complex' contains data from a type that maps to the name 'http://tempuri.org/:SampleComplexType'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'SampleComplexType' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
但是当我的其他应用程序(AspNew MVC)称之为:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<HelloComplex xmlns="http://tempuri.org/">
<complex xmlns:a="http://schemas.datacontract.org/2004/07/IssueCenter.Core" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Value>C#VALUE!</a:Value>
</complex>
</HelloComplex>
</s:Body>
</s:Envelope>
蚂蚁有效。
如何修复Android客户端请求?
注意:我知道命名空间差异,我已经尝试过这样做了。
答案 0 :(得分:0)
该服务不知道如何处理XML中的“ComplexType”类型属性,因此您基本上需要告诉服务端序列化程序它的含义。您可以通过以下几种方式执行此操作:要么添加DataContractResolver以告知序列化程序此未知类型ID的含义,要么您可以将类型(如果它存在于服务端)添加到“已知类型”列表中,该服务确切地知道如何处理它。我认为你应该使用DataContractResolver。
在框架的4.0版本中,WCF引入了数据合同解析器。而不是“静态地”定义已知类型的集合(例如,直到在.NET 4中直接在KnownTypeAttribute中指定类型),数据协定解析器提供了一些钩子,允许您在对象是时指定在序列化或反序列化时,CLR类型与XML中的名称/命名空间之间的映射将用于表示此“未知”类型。为此,您只需从DataContractResolver类继承并提供映射逻辑。
我认为这对你来说是更好的解决方案,因为你可能不想在服务器端创建虚拟类型只是为了解决这个问题,如果你要使用它就是你必须要做的KnownTypeAttribute。唯一要记住的是,解析器使序列化比使用“标准”已知类型功能更慢(因为已知类型是静态的,它们可以被缓存,并且不需要一直进行调用),所以要注意当使用解析器时,额外的功能在执行时间方面是有代价的。