Wsdl soap header is missing in the imported interface in Delphi 6

3.6k views Asked by At

I am trying to implement a webservice using Delphi 6. Web service uses soap version 1.2 and my delphi has a soap agent of 1.1. When I tried to import the wsdl, soap header "Autenticacao" is missing in the interface. Provider insists to send the 4 parameters as part of this soap header before calling the web service ? I have attached both my wsdl xml file and the imported pas file ?

Can anyone help me to set the parameters of "Autenticacao" ?

Thanks in advance .

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:\Projects\Delphi 6\WBWaiter\arquivonf_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. 
3

There are 3 answers

1
Wim ten Brink On

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.

0
Chris Thornton On

You can side-step the issue by altering the response XML during the RIO_AfterExecute method. Just use StringReplace to inject your header into the response, where you need it. We do something similar, but in our case we have some authentication stuff that doesn't appear in the WSDL at all, because it's not actually required by the destination service but is used by an intermediate XML gateway to authenticate the request. So we just "stuff it in there" with a stringreplace.

0
Sam On

If you move to Delphi 7 your options improve...

The Delphi 7 WSDL Importer (wsdlimp.exe) has an update that can be downloaded from Embarcadero ID: 24535, Delphi SOAP Runtime and Importer Update

Although it doesn't say that Delphi 6 is supported (could be technical or marketing reasons behind that), you could try using the downloaded wsdlimp.exe from the command line and then try the generated .pas file with your Delphi 6 project anyway.