ksoap2和WCF复杂类型

时间:2011-06-09 04:22:38

标签: wcf soap ksoap2

我正在使用kso​​ap2向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客户端请求?

注意:我知道命名空间差异,我已经尝试过这样做了。

1 个答案:

答案 0 :(得分:0)

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

在框架的4.0版本中,WCF引入了数据合同解析器。而不是“静态地”定义已知类型的集合(例如,直到在.NET 4中直接在KnownTypeAttribute中指定类型),数据协定解析器提供了一些钩子,允许您在对象是时指定在序列化或反序列化时,CLR类型与XML中的名称/命名空间之间的映射将用于表示此“未知”类型。为此,您只需从DataContractResolver类继承并提供映射逻辑。

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