English 中文(简体)
Delphi 6中导入的接口中缺少Wsdl soap头
原标题:Wsdl soap header is missing in the imported interface in Delphi 6

我正在尝试使用Delphi6实现一个Web服务。Web服务使用soap 1.2版本,我的delphi有一个soap代理1.1。当我尝试导入wsdl时,接口中缺少soap头“Autenticacao”。提供者坚持在调用web服务之前将4个参数作为这个soap头的一部分发送?我已经附加了我的wsdl xml文件和导入的pas文件?

有人能帮我设置“仙人掌”的参数吗?

提前谢谢。

Kind Regards Sinu

.xml file content

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="https://www.nfp.sp.gov.br/ws" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="https://www.nfp.sp.gov.br/ws" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="https://www.nfp.sp.gov.br/ws">
      <s:element name="Enviar">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="NomeArquivo" type="s:string"/>
            <s:element minOccurs="0" maxOccurs="1" name="ConteudoArquivo" type="s:string"/>
            <s:element minOccurs="0" maxOccurs="1" name="Observacoes" type="s:string"/>
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="EnviarResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="EnviarResult" type="s:string"/>
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="Autenticacao" type="tns:Autenticacao"/>
      <s:complexType name="Autenticacao">
        <s:attribute name="Usuario" type="s:string"/>
        <s:attribute name="Senha" type="s:string"/>
        <s:attribute name="CNPJ" type="s:string"/>
        <s:attribute name="CategoriaUsuario" type="s:unsignedByte" use="required"/>
        <s:anyAttribute/>
      </s:complexType>
      <s:element name="Consultar">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="Protocolo" type="s:string"/>
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="ConsultarResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ConsultarResult" type="s:string"/>
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="EnviarSoap12In">
    <wsdl:part name="parameters" element="tns:Enviar"/>
  </wsdl:message>
  <wsdl:message name="EnviarSoap12Out">
    <wsdl:part name="parameters" element="tns:EnviarResponse"/>
  </wsdl:message>
  <wsdl:message name="EnviarAutenticacao">
    <wsdl:part name="Autenticacao" element="tns:Autenticacao"/>
  </wsdl:message>
  <wsdl:message name="ConsultarSoap12In">
    <wsdl:part name="parameters" element="tns:Consultar"/>
  </wsdl:message>
  <wsdl:message name="ConsultarSoap12Out">
    <wsdl:part name="parameters" element="tns:ConsultarResponse"/>
  </wsdl:message>
  <wsdl:message name="ConsultarAutenticacao">
    <wsdl:part name="Autenticacao" element="tns:Autenticacao"/>
  </wsdl:message>
  <wsdl:portType name="ArquivoNF_Mod1Soap12">
    <wsdl:operation name="Enviar">
      <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">&lt;br /&gt;Este método deve ser usado para envio do arquivo de Nota Fiscal modelo 1/1A.&lt;br /&gt;Os parâmetros de autenticação, informados via SOAP Header, são:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Usuario&lt;/b&gt;: login do usuário que está fazendo a requisição de acordo com o perfil escolhido&lt;/li&gt;&lt;li&gt;&lt;b&gt;Senha&lt;/b&gt;: senha do usuário&lt;/li&gt;&lt;li&gt;&lt;b&gt;CNPJ&lt;/b&gt;: CNPJ do estabelecimento ao qual o usuário está vinculado e o arquivo pertence&lt;/li&gt;&lt;li&gt;&lt;b&gt;CategoriaUsuario&lt;/b&gt;: perfil do usuário informado (1 para contribuintes e 2 para contabilistas)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Os parâmetros do método são:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;NomeArquivo&lt;/b&gt;: nome do arquivo enviado&lt;/li&gt;&lt;li&gt;&lt;b&gt;ConteudoArquivo&lt;/b&gt;: conteúdo do arquivo enviado&lt;/li&gt;&lt;li&gt;&lt;b&gt;Observacoes&lt;/b&gt;: observações, caso existam, relativas ao arquivo ou envio&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;</wsdl:documentation>
      <wsdl:input message="tns:EnviarSoap12In"/>
      <wsdl:output message="tns:EnviarSoap12Out"/>
    </wsdl:operation>
    <wsdl:operation name="Consultar">
      <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">&lt;br /&gt;Este método é utilizado para consultar o resultado de processamento para um arquivo de Nota Fiscal modelo 1.&lt;br /&gt;Os parâmetros de autenticação, informados via SOAP Header, são:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Usuario&lt;/b&gt;: login do usuário que está fazendo a requisição de acordo com o perfil escolhido&lt;/li&gt;&lt;li&gt;&lt;b&gt;Senha&lt;/b&gt;: senha do usuário&lt;/li&gt;&lt;li&gt;&lt;b&gt;CNPJ&lt;/b&gt;: CNPJ do estabelecimento ao qual o usuário está vinculado e o arquivo pertence&lt;/li&gt;&lt;li&gt;&lt;b&gt;CategoriaUsuario&lt;/b&gt;: perfil do usuário informado (1 para contribuintes e 2 para contabilistas)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;O parâmetro do método é:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Protocolo&lt;/b&gt;: número do protocolo a ser consultado&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;</wsdl:documentation>
      <wsdl:input message="tns:ConsultarSoap12In"/>
      <wsdl:output message="tns:ConsultarSoap12Out"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ArquivoNF_Mod1Soap12" type="tns:ArquivoNF_Mod1Soap12">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Enviar">
      <soap12:operation soapAction="https://www.nfp.sp.gov.br/ws/Enviar" style="document"/>
      <wsdl:input>
        <soap12:body use="literal"/>
        <soap12:header message="tns:EnviarAutenticacao" part="Autenticacao" use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="Consultar">
      <soap12:operation soapAction="https://www.nfp.sp.gov.br/ws/Consultar" style="document"/>
      <wsdl:input>
        <soap12:body use="literal"/>
        <soap12:header message="tns:ConsultarAutenticacao" part="Autenticacao" use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ArquivoNF_Mod1">
    <wsdl:port name="ArquivoNF_Mod1Soap12" binding="tns:ArquivoNF_Mod1Soap12">
      <soap12:address location="https://www.nfp.fazenda.sp.gov.br/ws/arquivonf_mod1.asmx"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

.pas file content

// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : C:ProjectsDelphi 6WBWaiterarquivonf_mod1.asmx.xml
// Encoding : UTF-8
// Version  : 1.0
// (10/02/2011 4:37:33 p.m. - $Revision:   1.9.1.0.1.0.1.9  $)
// ************************************************************************ //

unit arquivonf_mod1;

interface

uses InvokeRegistry, Types, XSBuiltIns;

type

  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Borland types; however, they could also 
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:string          - "http://www.w3.org/2001/XMLSchema"

  ConsultarResponse    = class;                 { "https://www.nfp.sp.gov.br/ws" }
  Consultar            = class;                 { "https://www.nfp.sp.gov.br/ws" }
  EnviarResponse       = class;                 { "https://www.nfp.sp.gov.br/ws" }
  Enviar               = class;                 { "https://www.nfp.sp.gov.br/ws" }

  // ************************************************************************ //

  // ************************************************************************ //
  ConsultarResponse = class(TRemotable)
  private
    FConsultarResult: String;
  published
    property ConsultarResult: String read FConsultarResult write FConsultarResult;
  end;

  // ************************************************************************ //
  // 
  // ************************************************************************ //
  Consultar = class(TRemotable)
  private
    FProtocolo: String;
  published
    property Protocolo: String read FProtocolo write FProtocolo;
  end;

  // ************************************************************************ //
  // 
  // ************************************************************************ //
  EnviarResponse = class(TRemotable)
  private
    FEnviarResult: String;
  published
    property EnviarResult: String read FEnviarResult write FEnviarResult;
  end;

  // ************************************************************************ //
  // 
  // ************************************************************************ //
  Enviar = class(TRemotable)
  private
    FNomeArquivo: String;
    FConteudoArquivo: String;
    FObservacoes: String;
  published
    property NomeArquivo: String read FNomeArquivo write FNomeArquivo;
    property ConteudoArquivo: String read FConteudoArquivo write FConteudoArquivo;
    property Observacoes: String read FObservacoes write FObservacoes;
  end;

  // ************************************************************************ //
  // Namespace : 
  // binding   : ArquivoNF_Mod1Soap12
  // service   : ArquivoNF_Mod1
  // port      : ArquivoNF_Mod1Soap12
  // ************************************************************************ //
  ArquivoNF_Mod1Soap12 = interface(IInvokable)
  [ {AD787B4C-A2C5-BE98-12B8-A37CF0CEA897} ]
    function  Enviar(const parameters: Enviar): EnviarResponse; stdcall;
    function  Consultar(const parameters: Consultar): ConsultarResponse; stdcall;
  end;

implementation
  uses SOAPHTTPClient;

initialization
  InvRegistry.RegisterInterface(TypeInfo(ArquivoNF_Mod1Soap12),  https://www.nfp.sp.gov.br/ws ,  UTF-8 );
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ArquivoNF_Mod1Soap12),   );
  RemClassRegistry.RegisterXSClass(ConsultarResponse,  https://www.nfp.sp.gov.br/ws ,  ConsultarResponse );
  RemClassRegistry.RegisterXSClass(Consultar,  https://www.nfp.sp.gov.br/ws ,  Consultar );
  RemClassRegistry.RegisterXSClass(EnviarResponse,  https://www.nfp.sp.gov.br/ws ,  EnviarResponse );
  RemClassRegistry.RegisterXSClass(Enviar,  https://www.nfp.sp.gov.br/ws ,  Enviar );

end. 
问题回答

I think the easiest solution would be to upgrade to a newer Delphi version, preferably Delphi XE, which has better SOAP support. Delphi 6 isn t really suitable anymore for modern development. Especially the SOAPy part...
As an alternative, you could ask someone with Delphi XE to import the service for you in XE, then migrate the code back to Delphi 6. But I fear you d have too many incompatibilities if you d try that.
Yet another solution would include the use of Visual Studio to create a client proxy for your Delphi application. This happens to be a solution I had to choose in the past for some project. You would use C# to create a COM-enabled assembly which you can call from your Delphi application. This assembly then executes the calls to the web service. It s an irritating work-around but when you get it working, it works quite nice too.

如果您转到Delphi7,您的选项会有所改进。。。

Delphi 7 WSDL导入程序(wsdlimp.exe)有一个更新,可以从Embarcadero下载ID:24535,Delphi SOAP运行时和导入程序更新

虽然它没有说支持Delphi 6(可能是技术或市场原因),但您可以尝试使用从命令行下载的wsdlimp.exe,然后在Delphi 6项目中尝试生成的.pas文件。

您可以通过在RIO_AfterExecute方法期间更改响应XML来回避该问题。只需使用StringReplace将您的头插入到响应中,您需要它。我们做了类似的事情,但在我们的案例中,我们有一些根本没有出现在WSDL中的身份验证内容,因为目标服务实际上并不需要它,而是由中间XML网关用于对请求进行身份验证。所以我们只是用一个字符串“塞进去”。





相关问题
determining the character set to use

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta ...

Help with strange Delphi 5 IDE problems

Ok, I m going nuts here. For the last (almost) four years, I ve been putting up with some extremely bad behavior from my Delphi 5 IDE. Problems include: Seemingly random errors in coride50.bpl ...

How to write a Remote DataModule to run on a linux server?

i would like to know if there are any solution to do this. Does anyone? The big picture: I want to access data over the web, using my delphi thin clients. But i´would like to keep my server/service ...

How convert string to integer in Oxygene

In Delphi, there is a function StrToInt() that converts a string to an integer value; there is also IntToStr(), which does the reverse. These functions doesn t appear to be part of Oxygene, and I can ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签