我试图使用Suds与web服务通信,从服务中读取数据可以正常工作,但是写入会抛出错误。在
suds.WebFault: Server raised fault: 'The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:tagValues. The InnerException message was 'Element Value from namespace http://schemas.datacontract.org/2004/07/NOV.Api.Messages cannot have child contents to be deserialized as an object. Please use XmlNode[] to deserialize this pattern of XML.'. Please see InnerException for more details.'
XML生成的似乎没有添加必要的xsi:类型="xsd:内景““
制作:
<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>
期望:
^{pr2}$在四处寻找之后,我想试试ImportDoctor,看看能不能进去xsi:类型在
我补充道
schema_url = 'http://schemas.xmlsoap.org/soap/encoding/'
schema_import = Import(schema_url)
schema_doctor = ImportDoctor(schema_import)
和doctor=schema\u doctor中的doctor
这给了我一个额外的前缀和一个扩展的类型列表
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: Server raised fault: 'The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:tagValues. The InnerException message was 'Error in line 1 position 651. Element 'http://schemas.datacontract.org/2004/07/NOV.Api.Messages:Value' contains data from a type that maps to the name 'http://schemas.xm lsoap.org/soap/encoding/:int'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'int' 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.'
似乎有点接近,但似乎名称空间有些混乱?在
生成的完整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。我对肥皂缺乏一些基本的了解。。。在
这不是一个“答案”,因为这个问题是客户端问题。但我现在把这个放在这里是为了搜索引擎。在
问题是请求消息是一种复杂类型。在
我的解决方案是在服务器端。我的服务现在接受请求中的非类型化元素。 请求主体的服务器端解析必须知道请求模式。一旦发生这种情况,服务器就可以对请求进行类型检查和解析,而无需客户端键入元素。在
具体来说,我的错误来自于使用pythonzsi模块和Zope实现的服务。在
这里,我得到了关于复杂请求对象的提示:
http://pypi.python.org/pypi/z3c.soap/(请参阅ValidateEmailRequest)
在这里,我在ZSI上了一个速成班: Are there any working examples of Zolera SOAP Infrastructure (ZSI)?
这里还有不错的ZSI文档:http://pywebsvcs.sourceforge.net/zsi.html#SECTION0071100000000000000000
为了让ZSI满意,您只需创建一个表示请求消息的类,并向其添加一个类型代码。这就是为什么会看到很多服务指向“operation foo”和“fooRequest”和“fooResponse”,这样它们就可以将请求和响应对象作为xml复杂类型来输入。在
对于上面的例子,我将把类似这样的东西导入到正在解析soap请求主体的命名空间中。你可以变得更复杂,但这是所有必要的:
“标记值是什么?”在
^{pr2}$什么是品质?在
以此类推,直到你一直深入到所有的原始类型。在
我用Adding xsi:type and envelope namespace when using SUDS(https://stackoverflow.com/a/10977734/696768)的答案设法解决了这个问题
我不确定这是唯一可能的解决方案,对我来说,这似乎比其他任何东西都更像是一种黑客攻击,但是它对我当前的场景来说效果很好。在
我使用的解决方案是为客户机制作一个插件,寻找我需要的特定元素xsi:类型="xsd:内景,然后将这些属性添加到这些元素中。在
我最后使用的代码作为参考(从前面提到的stackoverflow问题中进行了一些小的调整):
然后我将plugins=[plugin]添加到客户端ctor。在
示例:
^{pr2}$相关问题 更多 >
编程相关推荐