2011-06-09 97 views
2

我使用kso​​ap2发送该请求,我的WCF web服务与Android客户端:ksoap2和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> 

ant it works。

如何解决我的Android客户端请求?

说明:我知道命名空间差异,我已经试着做出同样的结果。

回答

0

该服务不知道如何处理XML中的“ComplexType”类型属性,因此您基本上需要告诉服务端序列化器它的含义。你可以通过几种方式来实现:或者添加一个DataContractResolver,告诉序列化器这个未知类型ID的含义,或者你可以将类型(如果它存在于服务端)添加到“已知类型”列表中,那么该服务确切地知道如何处理它。我认为你应该使用DataContractResolver。

在框架的4.0版中,WCF引入了数据合约解析器。数据约定解析器提供了一些钩子,它们允许你指定对象是什么时候的对象,而不是“静态地”定义一组已知类型(比如直接在KnownTypeAttribute中指定类型)被序列化或反序列化,CLR类型和XML中的名称/名称空间之间的映射将用于表示这种“未知”类型。为此,您只需从DataContractResolver类继承并提供映射逻辑。

我认为这对你来说是更好的解决方案,因为你可能不想在服务器端创建一个虚拟类型来处理这个问题,这是你必须做的事情,如果你想要使用KnownTypeAttribute。唯一需要记住的是,解析器使得序列化比使用“标准”已知类型特征要慢(因为已知类型是静态的,它们可以被缓存并且不需要始终进行调用),所以要注意在使用解析器时,附加功能在执行时间方面具有代价。