Delphi HttpRio SOAPHTTPClient不会为命名空间变量添加前缀

时间:2016-05-03 12:28:29

标签: xml delphi soap delphi-7 afas-online

我正在开发一个SOAP服务/连接到AFAS,并且基于WSDL(受密码保护),delphi生成一个接口。

我可以使用HTTPRIO和GetConnector调用生成的接口,然后它会提供给我:

FGetAfas.GetData(FEnvironment, FUsername, FPassword, '', FConnectorID, '')

功能:

function FGetAfas(): GetConnectorSoap;
var
  HTTPRIO: THTTPRIO;
begin
  HTTPRIO := THTTPRIO.Create(nil);
  with HTTPRIO.HTTPWebNode do begin
    ConnectTimeout := 60000;
    SendTimeout := 60000;
    ReceiveTimeout := 60000;
    UserName := FDomain + '\' + FUsername;
    Password := FPassword;
  end;

  Result := GetGetConnectorSoap(False, FUrl, HTTPRIO);
end;

然后生成的肥皂调用如下所示:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:NS1="urn:Afas.Profit.Services">
  <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <NS1:GetData xmlns:NS1="urn:Afas.Profit.Services">
      <environmentId>ab1</environmentId>
      <userId>aaa</userId>
      <password>bbb</password>
      <connectorId>1</connectorId>
    </NS1:GetData>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

但是,接收服务器返回environmentId为空的警告。您可以在上面看到,但事实并非如此。

我已经发现了问题,但事实证明服务器期望子元素也以NS1名称空间为前缀。很像这样:(在这个例子中我会跳过身体和信封位)

<NS1:GetData xmlns:NS1="urn:Afas.Profit.Services">
  <NS1:environmentId>ab1</NS1:environmentId>
  <NS1:userId>aaa</NS1:userId>
  <NS1:password>bbb</NS1:password>
  <NS1:connectorId>1</NS1:connectorId>
</NS1:GetData>

当我在SoapUI中提出新请求时,一切正常。

因此,我们来到问题:

  • 1:服务器要求命名空间元素的子元素也具有命名空间前缀是正常的吗?

  • 2:有没有一种优雅的方法来确保delphi接口将名称空间前缀附加到值?一种方法是在HTTPRIO.OnBeforeExecute过程中执行stringreplace。但这似乎不是一种非常优雅的解决方法。

从WSDL加载时,SoapUI会生成以下请求:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:urn="urn:Afas.Profit.Services">
   <soap:Header/>
   <soap:Body>
      <urn:GetData>
         <!--Optional:-->
         <urn:environmentId>?</urn:environmentId>
         <!--Optional:-->
         <urn:userId>?</urn:userId>
         <!--Optional:-->
         <urn:password>?</urn:password>
         <!--Optional:-->
         <urn:logonAs>?</urn:logonAs>
         <!--Optional:-->
         <urn:connectorId>?</urn:connectorId>
         <!--Optional:-->
         <urn:filtersXml>?</urn:filtersXml>
      </urn:GetData>
   </soap:Body>
</soap:Envelope>

2 个答案:

答案 0 :(得分:0)

看看我们的一些,不,在每个元素上都需要名称空间是不正常的。 GetData父节点上的NS1应该覆盖您。但服务器的实施可能会有所不同....你并不是说你正在打什么服务。

我建议使用SoapUI创建一个模拟服务,然后更改您的端点以点击SoapUI模拟,看看它是否有效。如果是这样,那么问题在于服务器。哦,你仍然需要修改你的代码才能使用服务器,但是你会感到满意是正确的。

答案 1 :(得分:0)

尝试更新的WSDL导入程序。请参阅此链接问题中的Bruce McGee的答案: Delphi 2005 Web Services problem

他引用了D2007 WSDL Importer的链接:http://cc.embarcadero.com/Item/24535 这对我们帮助很大。