How to consume EFD-Reinf's WebService in C #? (Shipping Events)

2

I am starting the EFD-Reinf information submission tests, in C #. From Visual Studio, I added a Service Reference to my project with the URL:

  

link

I have the digital certificate installed on my machine. He requests permission to use the key:

It loads the services available, I click OK and the service is available to me. I can instantiate, etc.

I ask, how should I proceed from there?

For other WebServices, such as Post Office, I would do this: I instantiated, passed the parameters and WS returned me with the response, and EFD-Reinf does not know how to pass these parameters.

For those who have already developed, is this the best way to send EFD-Reinf events?

    
asked by anonymous 13.11.2018 / 14:43

1 answer

0

The main code to access the EFD-Reinf WebService is this:

using System.Net;
using System.ServiceModel;
using System.Security.Cryptography.X509Certificates;
using System.Xml.Linq;

public void EnviarLoteReinf()
{
   // Carrega o certificado digital a partir de um arquivo PFX, informando a senha.
   X509Certificate2 x509Cert = new X509Certificate2(caminhoArquivoPfx, senhaArquivoPfx);
   // Carrega o XML de lote a partir de um arquivo.
   // Mas os XMLs dos eventos devem ser assinados digitalmente antes de inseridos no XML de lote.
   // Para isso é possível usar a função SignXmlDoc() disponível na resposta abaixo:
   // https://pt.stackoverflow.com/a/277476/
   XDocument loteEventosXDoc = XDocument.Load(caminhoArquivoXml);

   var urlServicoEnvio = @"https://preprodefdreinf.receita.fazenda.gov.br/wsreinf/RecepcaoLoteReinf.svc";
   var address = new EndpointAddress(urlServicoEnvio);
   // BasicHttpsBinding está disponível somente a partir do .NET Framework 4.5.
   // Se estiver usando uma versão anterior, use a linha comentada abaixo.
   //var binding = new BasicHttpBinding(BasicHttpsSecurityMode.Transport);
   var binding = new BasicHttpsBinding();

   // Informa que será usado um certificado digital para acessar o serviço.
   binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

   // Veja essa pergunta para mais detalhes:
   // https://pt.stackoverflow.com/q/318351/
   ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

   // Cria o objeto cliente (do tipo System.ServiceModel.ClientBase) para acesso ao WebService.
   var wsClient = new ServiceReference2.RecepcaoLoteReinfClient(binding, address);
   // Passa o certificado digital para o objeto do tipo System.ServiceModel.ClientBase.
   wsClient.ClientCredentials.ClientCertificate.Certificate = x509Cert;

   // Veja: https://stackoverflow.com/a/49303859/
   wsClient.Open();
   // Chama o WebService de fato, passando o XML do lote.
   // O método espera um objeto do tipo XElement, e retorna outro objeto XElement.
   var retornoEnvioXElement = wsClient.ReceberLoteEventos(loteEventosXDoc.Root);
   wsClient.Close();
}

Some important (and not so much) points that are partially commented out in the code, or are related:

  • The XML that will be sent to the service is a batch file that will contain one or more EFD-Reinf events. These event XMLs must be signed individually before they are inserted into the batch. In this response there is an example function to sign the XML using the digital certificate;
  • The System.ServiceModel.BasicHttpsBinding class is only available from the .NET Framework 4.5, if you are using an earlier version, use the BasicHttpBinding class;
  • For more details on the ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls line, see this question ;
  • For some interesting information about System.ServiceModel.ClientBase.Open() see this answer ;
  • If you'd like to see an example exception handling returned by a WCF WebService, see this answer .

Here are some useful links to working with EFD-Reinf:

13.11.2018 / 19:30