使用Zeep(python)验证SOAP请求时出现问题

使用Zeep(python)验证SOAP请求时出现问题,soap,zeep,Soap,Zeep,我在通过Zeep获取SOAP请求时遇到问题,我得到一个(客户端)验证错误。。。我还使用SoapUI进行了测试,但没有给出相同的验证错误 下面的规范来自服务器。。。根据该规范,需要OrderStatus和SynchStatus来执行请求 <soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:web="WebServiceProvider"> <soa

我在通过Zeep获取SOAP请求时遇到问题,我得到一个(客户端)验证错误。。。我还使用SoapUI进行了测试,但没有给出相同的验证错误

下面的规范来自服务器。。。根据该规范,需要OrderStatus和SynchStatus来执行请求

<soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:web="WebServiceProvider">
   <soapenv:Header/>
   <soapenv:Body>
      <web:Order_Get>
         <!--Optional:-->
         <web:orderOptions>
            <web:FromDate>?</web:FromDate>
            <web:ToDate>?</web:ToDate>
            <web:OrderStatus>?</web:OrderStatus>
            <web:SynchStatus>?</web:SynchStatus>
            <!--Optional:-->
            <web:OrderNumber>?</web:OrderNumber>
            <web:FromOrderNumberToLastRecieved>?</web:FromOrderNumberToLastRecieved>
            <web:PaymentStatus>?</web:PaymentStatus>
         </web:orderOptions>
      </web:Order_Get>
   </soapenv:Body>
</soapenv:Envelope>
然后我尝试执行以下请求:

order_options = {
  'FromDate': '2021-03-30',
  'ToDate': '2021-03-31',
}
orders = api.service.Order_Get(orderOptions=order_options)
这将导致以下错误:

zeep.exceptions.ValidationError: Missing element OrderStatus (Order_Get.orderOptions.OrderStatus)
如果我将OrderStatus添加到请求中,我将得到一个验证错误,表明缺少SynchStatus。当该请求也被添加后,请求将被发送到服务器

也就是说,似乎zeep客户端在验证请求中的数据方面比服务器更严格。。。是否有办法强制客户端跳过此验证

非常感谢

似乎zeep客户端在验证请求中的数据方面比服务器更严格

看起来是这样

查看SoapUI基于WSDL生成的请求,您提到的两个字段是必需的:

 <web:orderOptions>
    <web:FromDate>?</web:FromDate>
    <web:ToDate>?</web:ToDate>
    <web:OrderStatus>?</web:OrderStatus>
    <web:SynchStatus>?</web:SynchStatus>
    <!--Optional:-->
    <web:OrderNumber>?</web:OrderNumber>
    <web:FromOrderNumberToLastRecieved>?</web:FromOrderNumberToLastRecieved>
    <web:PaymentStatus>?</web:PaymentStatus>
 </web:orderOptions>

?
?
?
?
?
?
?
因此,zeep客户端显示的错误是正确的。Zeep检查WSDL并生成相应的代码以使用契约中的类型。您的WSDL合同规定,
OrderStatus
SynchStatus
是强制性的。服务器没有验证它们的事实表明了一个问题:web服务没有遵守它自己的文档化契约

WSDL和web服务的行为应该是相同的。我建议您联系web服务所有者并询问有关此行为的信息。这可能是服务器上缺少验证,而您得到的只是验证的一些副作用,或者该行为是故意的,但有人忘记更新WSDL,说您也可以在没有这些参数的情况下进行调用

同时,解决方法非常简单。下载WSDL,将其更改为两个字段可选,然后将更改后的WSDL提供给zeep,以便生成代码,而不是使用原始WSDL。但是,您应该向web服务提供商澄清这一点。如果确实有人忽略了这一点,可能会在某个时候发现并修复它,从而使您的变通方法调用由于缺少字段而无法通过服务器验证

似乎zeep客户端在验证请求中的数据方面比服务器更严格

看起来是这样

查看SoapUI基于WSDL生成的请求,您提到的两个字段是必需的:

 <web:orderOptions>
    <web:FromDate>?</web:FromDate>
    <web:ToDate>?</web:ToDate>
    <web:OrderStatus>?</web:OrderStatus>
    <web:SynchStatus>?</web:SynchStatus>
    <!--Optional:-->
    <web:OrderNumber>?</web:OrderNumber>
    <web:FromOrderNumberToLastRecieved>?</web:FromOrderNumberToLastRecieved>
    <web:PaymentStatus>?</web:PaymentStatus>
 </web:orderOptions>

?
?
?
?
?
?
?
因此,zeep客户端显示的错误是正确的。Zeep检查WSDL并生成相应的代码以使用契约中的类型。您的WSDL合同规定,
OrderStatus
SynchStatus
是强制性的。服务器没有验证它们的事实表明了一个问题:web服务没有遵守它自己的文档化契约

WSDL和web服务的行为应该是相同的。我建议您联系web服务所有者并询问有关此行为的信息。这可能是服务器上缺少验证,而您得到的只是验证的一些副作用,或者该行为是故意的,但有人忘记更新WSDL,说您也可以在没有这些参数的情况下进行调用


同时,解决方法非常简单。下载WSDL,将其更改为两个字段可选,然后将更改后的WSDL提供给zeep,以便生成代码,而不是使用原始WSDL。但是,您应该向web服务提供商澄清这一点。如果确实忽略了某个人,这可能会在某个时候被发现并修复,使您的变通方法调用因缺少字段而无法通过服务器验证。

在本文中搜索了更多内容并找到了变通方法:

因此,在我的案例中,解决方案如下所示:

from zeep import xsd
...

order_options = {
  'FromDate': '2021-03-30',
  'ToDate': '2021-03-31',
  'OrderStatus': xsd.SkipValue,
  'SynchStatus': xsd.SkipValue,
}

response = api.service.Order_Get(orderOptions=order_options)

这将阻止zeep对OrderStatus和SynchStatus参数进行客户端验证。

在本文中搜索了更多信息并找到了解决方法:

因此,在我的案例中,解决方案如下所示:

from zeep import xsd
...

order_options = {
  'FromDate': '2021-03-30',
  'ToDate': '2021-03-31',
  'OrderStatus': xsd.SkipValue,
  'SynchStatus': xsd.SkipValue,
}

response = api.service.Order_Get(orderOptions=order_options)
这将阻止zeep对参数OrderStatus和SynchStatus进行客户端验证。

zeep将在调用操作时自动验证是否设置了所有必需的值。如果要强制忽略某个值并将其从生成的XML中删除,则可以指定zeep.xsd.SkipValue常量。很好的发现+1Zeep将在调用操作时自动验证是否设置了所有必需的值。如果要强制忽略某个值并将其从生成的XML中删除,则可以指定zeep.xsd.SkipValue常量。很好的发现+1.