1
I’m new to the community and I’m developing a C# application for EFD-REINF. I had a problem with the subscription and I received a great help from Pedro in this link.
I’m still not able to send XML from the R-1000 event to the remote production server, as I’m having problems with my signature: "Poorly formed Reference Element." in line "signedXml.Computesignature()". Someone else has been through this trouble?
Basically, I created my Envioreinf class by calling individual methods for each of the information to be sent: R-1000 , R-2010, R-2020...(I believe there may be a simpler way to do this, but since I don’t have much experience with Web Service I implemented it this way) as follows:
//R-1000
public bool EnvioEventoevtInfoContribuinte(Empresa objEmpresa, DateTime periodoApuracao)
{
try
{
EventosREINF auxiliar = new EventosREINF();
_reinf.evtInfoContri = auxiliar.EnviarEvtInfoContri(objEmpresa, periodoApuracao);
ReinfEvtInfoContri evtInfoContri = _reinf.evtInfoContri;
//serializa o evento informações do Contribuinte
string xmlEventoInclusao = XMLConverte.SerializaObjeto<ReinfEvtInfoContri>(evtInfoContri);
//Exibe a lista de certificados para o usuário selecionar
X509Certificate2 oX509Cert = BuscarCertificadoEmpresa();
//Adiciona a assinatura digital ao evento
XmlDocument xmlDoc = new XmlDocument();
Assinar(xmlDoc, oX509Cert, xmlEventoInclusao);
//XmlDocument xmlReinf = Assinar(xmlEventoInclusao, oX509Cert);
//Inicializa o vetor de eventos do lote a ser enviado
REINF.Model.v1_04.TArquivoeReinf[] xmlsEvento = new REINF.Model.v1_04.TArquivoeReinf[1];
//Adicionar Arquivo XML ao array de Eventos do Lote
REINF.Model.v1_04.TArquivoeReinf arquivoR_1000 = new REINF.Model.v1_04.TArquivoeReinf
{
id = objEmpresa.ToString(),
Any = xmlDoc.DocumentElement
};
xmlsEvento[0] = arquivoR_1000;
//Adiciona o xml do evento de informações do Contribuinte ao xml do evento de envio
XmlDocument xmlDocEventoEnvio = AdicionarLoteAoEventoEnvio(xmlsEvento, objEmpresa);
//Envia arquivo xml para o web service e obtém o xml de retorno
XmlElement xmlRetorno = EnviarXML(xmlDocEventoEnvio, oX509Cert);
}
catch
{
throw;
}
return true;
}
//R-2010
public bool EnvioEventoevtServTom(List<NotaFiscal> objNotasFiscais, Empresa objEmpresa, DateTime periodoApuracao)
{
try
{
ReinfEvtServTom reinfEvtServTom = new ReinfEvtServTom();
EventosREINF auxiliar = new EventosREINF();
_reinf.evtServTom = auxiliar.EnviarevtServTom(objNotasFiscais, objEmpresa, periodoApuracao);
//Exibe a lista de certificados para o usuário selecionar
X509Certificate2 oX509Cert = BuscarCertificadoEmpresa();
//Inicializa o vetor de eventos do lote a ser enviado
REINF.Model.v1_04.TArquivoeReinf[] xmlsEvento = ComunicacaoREINF(objNotasFiscais, oX509Cert).ToArray();
//Adicionar Arquivo XML ao array de Eventos do Lote
REINF.Model.v1_04.TArquivoeReinf arquivoR_2010 = new REINF.Model.v1_04.TArquivoeReinf
{
id = objEmpresa.ToString(),
};
xmlsEvento[0] = arquivoR_2010;
//Adiciona o xml do evento de informações do Contribuinte ao xml do evento de envio
XmlDocument xmlR2010 = AdicionarLoteAoEventoEnvio(xmlsEvento, objEmpresa);
//Envia arquivo xml para o web service e obtém o xml de retorno
XmlElement xmlRetorno = EnviarXML(xmlR2010, oX509Cert);
//Converte o xml de retorno para a classe retorno de envio
ReinfRetornoLoteEventos reinfRetornoLoteEventos = XMLConverte.DeserializaObjeto<ReinfRetornoLoteEventos>(xmlRetorno.OuterXml);
}
catch
{
throw;
}
return true;
}
//R-2020
public bool EnvioEventoevtServPrest(List<NotaFiscal> objNotasFiscais, Empresa objEmpresa, DateTime periodoApuracao)
{
try
{
ReinfEvtServPrest reinfEvtServPrest = new ReinfEvtServPrest();
EventosREINF auxiliar = new EventosREINF();
_reinf.evtServPrest = auxiliar.EnviarevtServPrest(objNotasFiscais, objEmpresa, periodoApuracao);
//Exibe a lista de certificados para o usuário selecionar
X509Certificate2 oX509Cert = BuscarCertificadoEmpresa();
//Inicializa o vetor de eventos do lote a ser enviado
REINF.Model.v1_04.TArquivoeReinf[] xmlsEvento = ComunicacaoREINF(objNotasFiscais, oX509Cert).ToArray();
//Adicionar Arquivo XML ao array de Eventos do Lote
REINF.Model.v1_04.TArquivoeReinf arquivoR_2020 = new REINF.Model.v1_04.TArquivoeReinf
{
id = objEmpresa.ToString(),
};
xmlsEvento[0] = arquivoR_2020;
//Adiciona o xml do evento de informações do Contribuinte ao xml do evento de envio
XmlDocument xmlR2100 = AdicionarLoteAoEventoEnvio(xmlsEvento, objEmpresa);
//Envia arquivo xml para o web service e obtém o xml de retorno
XmlElement xmlRetorno = EnviarXML(xmlR2100, oX509Cert);
//Converte o xml de retorno para a classe retorno de envio
ReinfRetornoLoteEventos reinfRetornoLoteEventos = XMLConverte.DeserializaObjeto<ReinfRetornoLoteEventos>(xmlRetorno.OuterXml);
}
catch
{
throw;
}
return true;
}
private List<TArquivoeReinf> ComunicacaoREINF(List<NotaFiscal> objNotasFiscais, X509Certificate2 oX509Cert)
{
List<TArquivoeReinf> loteEnvio = new List<TArquivoeReinf>();
foreach (NotaFiscal notaFiscal in objNotasFiscais)
{
ReinfLoteEventos reinfLoteEventos = new ReinfLoteEventos();
string xmlEventoInfoContribuinte = XMLConverte.SerializaObjeto<ReinfLoteEventos>(reinfLoteEventos);
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlEventoInfoContribuinte);
TArquivoeReinf ObjArqXmlFilho = new TArquivoeReinf
{
id = notaFiscal.TipoDocumento.Id.ToString(),
Any = xmlDoc.DocumentElement
};
loteEnvio.Add(ObjArqXmlFilho);
}
return loteEnvio;
}
public ReinfRetornoLoteEventos RetornoLoteEventos(ReinfRetornoLoteEventos retornoLoteEventosInicial, string xmlRetorno)
{
try
{
ReinfRetornoLoteEventos reinfRetornoLoteEventos = new ReinfRetornoLoteEventos();
reinfRetornoLoteEventos = XMLConverte.DeserializaObjeto<ReinfRetornoLoteEventos>(xmlRetorno);
ReinfRetornoLoteEventosRetornoEventos reinfRetornoLoteEventosRetornoEventos = new ReinfRetornoLoteEventosRetornoEventos
{
evento = reinfRetornoLoteEventos.retornoEventos.evento
};
REINF.Model.ConsultaEvento_ProducaoRestrita.ConsultaInformacoesConsolidadasRequest consultaInformacoesConsolidadasRequest = new ConsultaEvento_ProducaoRestrita.ConsultaInformacoesConsolidadasRequest
{
Body = new ConsultaEvento_ProducaoRestrita.ConsultaInformacoesConsolidadasRequestBody()
};
//consultaInformacoesConsolidadasRequest.Body.numeroInscricaoContribuinte = "";
//consultaInformacoesConsolidadasRequest.Body.numeroProtocoloFechamento = "";
//consultaInformacoesConsolidadasRequest.Body.tipoInscricaoContribuinte = "";
REINF.Model.ConsultaEvento_ProducaoRestrita.ConsultasReinfClient consultasReinfClient = new ConsultaEvento_ProducaoRestrita.ConsultasReinfClient();
}
catch
{
throw;
}
return retornoLoteEventosInicial;
}
private XmlDocument AdicionarLoteAoEventoEnvio(TArquivoeReinf[] xmlsEvento, Empresa objEmpresa)
{
//Leiaute Mensagem Entrada
ReinfLoteEventos reinfLoteEventos = new ReinfLoteEventos
{
evento = new TArquivoeReinf[1]
};
reinfLoteEventos.evento = xmlsEvento;
//Serializa objeto evento de envio
string xmlEventoEnvio = XMLConverte.SerializaObjeto<ReinfLoteEventos>(reinfLoteEventos);
//Converte xml do evento envio para XMLDocumente que será transmitido para o web service
XmlDocument xmlDocEventoEnvio = XMLConverte.ConverterXMLParaXMLDocument(xmlEventoEnvio);
return xmlDocEventoEnvio;
}
private static string UTF8ByteArrayToString(byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
string constructedString = encoding.GetString(characters);
return (constructedString);
}
public void Assinar(XmlDocument xmlDoc, X509Certificate2 X509Cert, string xmlEventoInclusao)
{
// Cria o objeto SignedXml baseado no XmlDocument passado.
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SigningKey = X509Cert.PrivateKey;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
// Checa se foi informado um URI para a referência, se foi acrescenta o "#" no começo.
xmlEventoInclusao = String.IsNullOrEmpty(xmlEventoInclusao) ? "" : $"#{xmlEventoInclusao}";
Reference reference = new Reference(xmlEventoInclusao);
reference.Id = _reinf.evtInfoContri.id;
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigC14NTransform());
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signedXml.AddReference(reference);
// Carrega o certificado em um objeto KeyInfoX509Data e o adiciona ao objeto KeyInfo.
KeyInfo KeyInfo = new KeyInfo();
KeyInfo.AddClause(new KeyInfoX509Data(X509Cert));
signedXml.KeyInfo = KeyInfo;
// Calcula a assinatura.
signedXml.ComputeSignature();
// Obtém a representação XML da assinatura e a armazena em um objeto XmlElement.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Acrescenta o elemento ao documento XML.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
// Se o primeiro nó do documento for o nó de declaração XML
// '<?xml version="1.0" encoding="utf-8"?>', remove ele.
if (xmlDoc.FirstChild is XmlDeclaration)
xmlDoc.RemoveChild(xmlDoc.FirstChild);
}
private X509Certificate2 BuscarCertificadoEmpresa()
{
X509Certificate2 cert = null;
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
X509Certificate2Collection certcollection = (X509Certificate2Collection)store.Certificates;
// pick a certificate from the store
cert = X509Certificate2UI.SelectFromCollection(certcollection,
"Autenticação do Certificado",
"Informe um certificao válido", X509SelectionFlag.SingleSelection)[0];
store.Close();
return cert;
}
private XmlElement EnviarXML(XmlDocument xmlDocEventoEnvio, X509Certificate2 oX509Cert)
{
XmlElement xmlResult = null;
var urlServicoEnvio = @"https://preprodefdreinf.receita.fazenda.gov.br/wsreinf/RecepcaoLoteReinf.svc";
var address = new EndpointAddress(urlServicoEnvio);
var binding = new BasicHttpsBinding();
// Informa que será usado um certificado digital para acessar o serviço.
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
// Cria o objeto cliente (do tipo System.ServiceModel.ClientBase) para acesso ao WebService.
var recepcaoLoteReinfClient = new RecepcaoLoteReinfClient(binding, address);
// Passa o certificado digital para o objeto do tipo System.ServiceModel.ClientBase.
recepcaoLoteReinfClient.ClientCredentials.ClientCertificate.Certificate = oX509Cert;
// Chama o WebService de fato, passando o XML do lote.
recepcaoLoteReinfClient.Open();
// O método espera um objeto do tipo XElement, e retorna outro objeto XElement.
//xmlResult = recepcaoLoteReinfClient.ReceberLoteEventos(xmlDoc.DocumentElement);
var retornoEnvioXElement = recepcaoLoteReinfClient.ReceberLoteEventos((XElement.Parse(xmlDocEventoEnvio.OuterXml)));
recepcaoLoteReinfClient.Close();
return xmlResult;
}
private bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'",
certificate.Subject,
sslPolicyErrors.ToString());
return false;
}
EDITION
Follow the XML that is being generated by hiding personal information:
<?xml version="1.0" encoding="utf-8"?>
<Reinf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.reinf.esocial.gov.br/schemas/envioLoteEventos/v1_04_00">
<evtInfoContri id="ID1000000000000002018121815063800001" xmlns="http://www.w3.org/2000/09/xmldsig#">
<ideEvento>
<tpAmb>2</tpAmb>
<procEmi>1</procEmi>
<verProc>1.0.0.0</verProc>
</ideEvento>
<ideContri>
<tpInsc>1</tpInsc>
<nrInsc>00000000000000</nrInsc>
</ideContri>
<infoContri>
<inclusao>
<idePeriodo>
<iniValid>2018-12</iniValid>
</idePeriodo>
<infoCadastro>
<classTrib>1</classTrib>
<indEscrituracao>0</indEscrituracao>
<indDesoneracao>0</indDesoneracao>
<indAcordoIsenMulta>0</indAcordoIsenMulta>
<contato>
<nmCtt>Nome Contato</nmCtt>
<cpfCtt>00000000000</cpfCtt>
<foneFixo>0000000000</foneFixo>
</contato>
<softHouse>
<cnpjSoftHouse>00000000000000</cnpjSoftHouse>
<nmRazao>Empresa</nmRazao>
<nmCont>Contato</nmCont>
</softHouse>
</infoCadastro>
</inclusao>
</infoContri>
</evtInfoContri>
</Reinf>
Hi Pedro, thank you so much for your help. The "_reinf.evtInfoContri.id" field is actually a function I created to pick up the response from the "evtInfoContri.id" field where I followed the advice of your other answer. I added the "#" and I still continue with that problem. I don’t know if it has anything to do with checking the posts about Reinf, my XML is containing the xmlns:xsi and xmlns:xsd elements, which are usually automatically added by the serializer and I don’t know how to remove this from my XML.
– User1012
About the
reference.Id
: But does this ID you are reporting exist in XML? Post your XML in the question, and the value being reported in the fieldreference.Id
, when the error occurs. About the attributesxmlns:xsi
andxmlns:xsd
, see item 3 of that reply: C# - EFD Reinf v1_04_00 - How to instantiate and fill all Event properties?.– Pedro Gaspar
I saw the XML you are trying to send. The value you are reporting in the field
reference.Id
is"#ID100000000000002018121809024900001"
? It should be this (although he is wrong, see item 2 of that answer to see how this ID should be composed)(or did you reset the start of the ID intentionally to not show the company’s CNPJ? ). I also saw that you’re putting the attributexmlns
in the elements<ideEvento>
,<ideContri>
and<infoContri>
, but this attribute should only appear in the root element<Reinf>
.– Pedro Gaspar
I believe the value in Reset. Id is correct as I followed the rule of the orientation manual. About XML, I got some advances yesterday and will post the new XML now. However I’m still having problems related to my Ference.URI
– User1012
But what is the exact amount you are reporting on
reference.Id
? It needs to be exactly the value that is in the attributeid
of the element<evtInfoContri>
, added character"#"
at first.– Pedro Gaspar
Actually I followed your guidance as you guided me in that other post; I’m taking the result of the reinf.evtInfoContri.id field (ID+1+CNPJ+AAAAMMDDHHMMSS+00001) and adding # at the beginning. I have now checked the documentation and it says that the last fields would be the sequential number of the key, but I am increasing with 00001. This is correct?
– User1012
Yeah, actually that last part, the sequential number, is just to make sure the ID will be unique. Suppose on 12/19/2018, at 10:50:31, you sent 3 events. Each one must have a unique ID, so the first would have final 00001, the second 00002 and the third 00003. And even reporting on
reference.Id
exactly the same ID that is in XML, preceded by#
, you are receiving the same error, from "Badly formed Reference element"?– Pedro Gaspar
Yes, I want to send only the R-1000 event for testing, but in the signature part that calculates the signature I get this error from Visual Studio. Is it necessary to inform the Referral.URI? If so, what is the value of this field?
– User1012
In the case of eSocial
reference.Id
should not be informed, and then the signature is made throughout the XML document, but in the EFD-Reinf it seems necessary to inform thereference.Id
, and in such a case shall be informed"#" + {Atributo ID do elemento 'evtInfoContri'}
. But his element<evtInfoContri>
should not have an attribute eitherxmlns
, let alone referencing the schema of XML Signature:"http://www.w3.org/2000/09/xmldsig#"
.– Pedro Gaspar
I understood, I also realized that my XML is not calling the loteEventos, from Reinf it already goes straight to the <evtInfoContri>. I guess that’s getting in the way of my routine, too.
– User1012
No, that’s right. This XML is the event, the element
loteEventos
is from the batch XML. Then you need to take this event XML and embed it in batch XML.– Pedro Gaspar
@User1012, did my answer answer your question? If you have answered it, please mark it as accepted by clicking on the visa sign ( ). But do this only when any answer has answered your original question. When you reach 15 reputation points you can also vote in favour of an answer or question. See: Someone answered me and Why vote?. Also do the [tour], for an initial explanation of how the site works.
– Pedro Gaspar
Hi Pedro, answered yes my dear. I clicked on visa more still need to achieve 15 pts of reputation :(
– User1012