我正在尝试使用 Suds 与 Web 服务通信,从服务中读取工作正常,但是写入会引发错误。
suds.WebFault:服务器引发错误:'格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数http://tempuri.org/:tagValues时出错。InnerException 消息是“来自命名空间 http://schemas.datacontract.org/2004/07/NOV.Api.Messages的元素值不能将子内容反序列化为对象。请使用 XmlNode[] 反序列化这种 XML 模式。'。有关更多详细信息,请参阅 InnerException。
XML 生成的似乎没有添加必要的 xsi:type="xsd:int"
出品:
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value>23</ns1:Value>
</ns1:TagValue>
预期的:
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="xsd:int">23</ns1:Value>
</ns1:TagValue>
在四处搜索后,我想尝试 ImportDoctor 看看我是否可以进入 xsi:type
我添加了
schema_url = 'http://schemas.xmlsoap.org/soap/encoding/'
schema_import = Import(schema_url)
schema_doctor = ImportDoctor(schema_import)
和客户端ctor中的医生=模式医生
这现在给了我一个额外的前缀和一个扩展得多的类型列表
Prefixes (4)
ns0 = "http://schemas.datacontract.org/2004/07/NOV.Api.Messages"
ns1 = "http://schemas.microsoft.com/2003/10/Serialization/"
ns2 = "http://schemas.xmlsoap.org/soap/encoding/"
ns3 = "http://tempuri.org/"
我现在有一个 ns2:int
我使用工厂创建了一个 ns2:int 类型的对象,将其值设置为 23
发送时,我得到以下 XML:
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="ns2:int">23</ns1:Value>
</ns1:TagValue>
现在尝试发送时出现以下异常:
suds.WebFault:服务器引发错误:'格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数http://tempuri.org/:tagValues时出错。InnerException 消息是“第 1 行位置 651 中的错误。元素“http://schemas.datacontract.org/2004/07/NOV.Api.Messages:Value”包含映射到名称“http:/”的类型的数据/schemas.xm lsoap.org/soap/encoding/:int'。反序列化器不知道映射到此名称的任何类型。考虑使用 DataContractResolver 或将与“int”对应的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。
似乎稍微接近一点,但似乎命名空间有些混乱?
生成的完整 XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns3="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://tempuri.org/" xmlns:ns1="http://schemas.datacontract.org/2004/07/NOV.Api.Messages" xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns3:Body>
<ns0:WriteRealtimeValues>
<ns0:tagValues>
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="ns2:int">23</ns1:Value>
</ns1:TagValue>
</ns0:tagValues>
</ns0:WriteRealtimeValues>
</ns3:Body>
</SOAP-ENV:Envelope>
作为参考,我使用以下代码创建客户端
credentials = dict(username='%s' % (username), password='%s' % password)
url= "http://%s:%s/TagValueWriteService?wsdl" % (ip,port)
self.transport = HttpAuthenticated(**credentials)
suds.client.Client.__init__(self,url, transport=self.transport, cache=None,doctor=schema_doctor)
stackoverflow 上似乎有几个类似的问题,其中大多数以与我尝试类似的方式提到 ImportDoctor。我怀疑我缺乏对 SOAP 的一些基本理解......