Add SOAP Header in SOAP C #

1

I'm trying to add a custom header in a SOAP service using C # . I've tried everything and I have not found a solution that works.

I am adding the C # Web Services service. I've already tried to override GetWebRequest , but it did not work.

The WSDL is this link

Example how should be

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://app.omie.com.br/api/v1/geral/clientes/?WSDL">
       <soapenv:Header>
          <app_key>123456789</app_key>
          <app_secret>topSecret</app_secret>
       </soapenv:Header>
   ....

Test code

static void Main(string[] args)
{
    var servico = new omie.Produto.ProdutosCadastro();            
    servico.autenticacao = new omie.Produto.Autenticacao();
    servico.autenticacao.app_key = "123456";
    servico.autenticacao.app_secret = "123456789";

    var dados = new omie.Produto.produto_servico_list_request();
    dados.pagina = "1";
    dados.registros_por_pagina = "50";
    dados.apenas_importado_api = "N";
    dados.filtrar_apenas_omiepdv = "N";

    var produtos = servico.ListarProdutosResumido(dados);

    Console.WriteLine(produtos.total_de_registros.ToString());
}

The test code was a suggestion of this post

link Search by text:

  

That was already described in my previous post

In addition, the SOAP class has been extended with these elements:

namespace omieTestes.omie.Produto
{
    public partial class ProdutosCadastro : System.Web.Services.Protocols.SoapHttpClientProtocol
    {
        public Autenticacao autenticacao;
    }

    //[XmlRoot(Namespace = "http://app.omie.com.br/autenticacao")]    
    public class Autenticacao : SoapHeader
    {
        public string app_key;
        public string app_secret;
    }
}

What I found to be bad is that updating the reference loses the implementation:

[System.Web.Services.Protocols.SoapRpcMethodAttribute("http://app.omie.com.br/api/v1/geral/produtos/?WSDLListarProdutosResumido", RequestNamespace="http://app.omie.com.br/api/v1/geral/produtos/?WSDL", ResponseNamespace="http://app.omie.com.br/api/v1/geral/produtos/?WSDL")]
    [SoapHeader("autenticacao", Direction = SoapHeaderDirection.In)]
    [return: System.Xml.Serialization.SoapElementAttribute("produto_servico_list_response")]        
    public produto_servico_list_response ListarProdutosResumido(produto_servico_list_request produto_servico_list_request) {
        object[] results = this.Invoke("ListarProdutosResumido", new object[] {
                    produto_servico_list_request});
        return ((produto_servico_list_response)(results[0]));
    }

Line placed in the hand

[SoapHeader("autenticacao", Direction = SoapHeaderDirection.In)]
    
asked by anonymous 13.10.2016 / 15:42

2 answers

1

This implementation seems a bit complicated. I have several services here that use values in Header , I'll show you two solutions that can serve you:

Assign values in Header directly in Endpoint of configuration file :
This is cool because services that have configuration files do not need to have the Header configuration in the code, unless your service creates the ServiceHost in the code. Hosted services in IIS can send information to the Header just by adding this to the Endpoint.

<client>
  <endpoint address="http://dominio/NomeServico.svc"
      binding="basicHttpBinding" contract="Contrato" name="NomeConfiguracao">
    <headers>
        <app_key>123456789</app_key>
        <app_secret>topSecret</app_secret>
    </headers>
  </endpoint>
</client>

This is the simplest way to do it.

Manipulating Endpoint in Code :
You can manipulate Endpoint after creating your client and before calling an operation. This is interesting because you can pass variable values and also that are not exposed in the configuration file, but you have to compile the code:

ServicoWcf cliente = new ServicoWcf();
var endpointPersonalizado = new EndpointAddressBuilder(cliente.Endpoint.Address);
endpointPersonalizado.Headers.Add( AddressHeader.CreateAddressHeader("app_key", string.Empty, "123456789")); 
endpointPersonalizado.Headers.Add( AddressHeader.CreateAddressHeader("app_secret", string.Empty, "topSecret")); 
cliente.Endpoint.Address = endpointPersonalizado.ToEndpointAddress();

You can also manipulate the OperationContextScope on the client and add Header , but I prefer the implementations above. Hope it helps.

    
14.10.2016 / 13:06
1

Try doing the following:

  ProdutoCadastroService.ProdutosCadastroSoapClient produtoCadastroWS = new    ProdutoCadastroService.ProdutosCadastroSoapClient();
  autenticaWsHeader(produtoCadastroWS);

  private static void autenticaWsHeader(ProdutosCadastroSoapClient produtoCadastroWS)
  {
        new OperationContextScope(produtoCadastroWS.InnerChannel);

        HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
        requestMessage.Headers["Username"] = "admin";
        requestMessage.Headers["Password"] = "123";
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
  }
    
14.10.2016 / 14:16