Geração de XML, validação e assinatura digital
Olá pessoal.
Estou disponibilizando um sistema de exemplo para geração de XML, validação e assinatura digital.
Atenção: A classe disponibilizada foi bastante alterada daquela que eu utilizo nas empresas no dia a dia, visando torna-la ainda mais automatizada com Reflection, portanto, não testei todas as situações possíveis, mas já aviso antecipadamente que qualquer problema com a classe vocês podem perguntar que vou ajustando.
Antes de tudo, esta classe não é para ser um exemplo demonstrando a melhor forma de se gerar um XML para NFe, na verdade quando iniciei o desenvolvimento a intenção era uma geração de XML com manutenção fácil para que no futuro as alterações de Layout fossem o mais simples possível.
Portanto, explicando basicamente, a classe foi inteiramente escrita conforme o manual de Integração, utiliza Reflection para uma geração mais automatizada e atributos para facilitar a formatação e outras configurações do XML. Acredito que o meu objetivo inicial com ela, que era ter uma classe de fácil manutenção foi atingida.
Vou começar explicando como a classe funciona e no final deste posto você encontra um aplicativo exemplo com a classe em uso. No meu sistema original esta classe está mais organizada, mas para o exemplo, coloquei as classes um pouco bagunçadas dentro de arquivos, mas acredito que está bem fácil de entender.
Bom, a classe não tem muito segredo, foi inteiramente digitada, é necessário apenas explicar alguns dos recursos que implementei.
Atributos
Entre as várias propriedades da classe, em algumas você encontra atributos como no exemplo abaixo:
[Formato("#####0.0000", "en-US")]
public decimal qCom { get; set; }
O Atributo [Formato] define o formato que o valor precisa no XML, além de informar a cultura, como “en-US” ou “pt-br”.
[Obrigatorio]
public string IE { get; set; }
O Atributo [Obrigatorio] define se o campo deve sair no XML mesmo quando não tiver um valor definido, como o IE por exemplo, que mesmo que esteja em branco deve ser informado no XML (
Além disso, várias propriedades podem ser nulas, como esta no exemplo abaixo:
public decimal? qTrib { get; set; }
Estas propriedades serão ignoradas pelo reflection se não tiverem um valor definido, utilize quando a TAG não deve ser informada no XML quando não possuir um valor.
Geração do XML
Pretendo explicar basicamente como desenvolvi a geração do XML através do Reflection. Vale lembrar que talvez algumas coisas devem ser arrumadas aqui ainda, visto que para este Post no Blog eu alterei a classe visando tornar ela ainda mais automatizada. Além disso, não me crucifiquem por algumas linhas de código, em algumas funções eu realmente não encontrei uma melhor de forma de fazer, mas uma das razões de postar esta classe é ter um feedback de vocês e melhorar ela ainda mais
Com a classe preenchida, a geração do XML é simples:
NFe teste = new NFe();
//Código para preencher a classe... no exemplo ele está disponível, aqui resolvi economizar espaço pulando esta parte
XmlDocument xmlGerado = teste.GerarXML();
//Salva uma cópia do XML não assinado - ATENÇÃO - se você está utilizando Windows Vista/7/Server, salvar na Unidade C pode não ser possível caso o VS2008 não esteja rodando como administrador
xmlGerado.Save("c:\\testeXMLNaoAssinado.xml");
//Seleciona o certificado
X509Certificate2 certificado = CertificadoDigital.SelecionarCertificado();
//assina o xml
XmlDocument xmlAssinado = CertificadoDigital.Assinar(xmlGerado, "infNFe", certificado);
//Valida o XML assinado
string resultado = ValidaXML.ValidarXML(xmlAssinado);
if (resultado.Trim().Length == 0)
resultado = "Xml gerado com sucesso, nenhum erro encontrado";
//Opcional - Função para gerar o Lote e deixar o arquivo pronto para ser enviado.
//teste.GerarLoteNfe(ref xmlAssinado);
//Importante:
//Salvar através do TextWriter evita que o XML saia formatado no arquivo, desta forma o mesmo
//pode ser rejeitado por alguns estados e/ou não validar nos programas teste
using (XmlTextWriter xmltw = new XmlTextWriter("C:\\testeXML.xml", new UTF8Encoding(false)))
{
xmlAssinado.WriteTo(xmltw);
xmltw.Close();
Eis a função GerarXML() – Veja os comentários no código para entender melhor
public XmlDocument GerarXML()
{
XmlWriterSettings configXML = new XmlWriterSettings();
configXML.Indent = true;
configXML.IndentChars = "";
configXML.NewLineOnAttributes = false;
configXML.OmitXmlDeclaration = false;
Stream xmlSaida = new MemoryStream();
XmlWriter oXmlGravar = XmlWriter.Create(xmlSaida, configXML);
oXmlGravar.WriteStartDocument();
oXmlGravar.WriteStartElement("NFe","http://www.portalfiscal.inf.br/nfe"); //abre nfe
oXmlGravar.WriteStartElement("infNFe");
oXmlGravar.WriteAttributeString("xmlns","xsi",null,"http://www.w3.org/2001/XMLSchema-instance");
oXmlGravar.WriteAttributeString("Id", "NFe" + Id.ToString());
oXmlGravar.WriteAttributeString("versao", versao.ToString());
Type tipoObjeto;
tipoObjeto = infNFE.Ide.GetType();
PropertyInfo[] propriedades;
propriedades = tipoObjeto.GetProperties();
//A Função objetoParaXML utiliza o reflection para ler as propriedades da classe e gerar o XML
objetoParaXML(oXmlGravar, infNFE.Ide,false);
objetoParaXML(oXmlGravar, infNFE.Emit,false);
objetoParaXML(oXmlGravar, infNFE.Dest, false);
foreach (infNFE.det detalhe in infNFE.Det)
{
oXmlGravar.WriteStartElement("det");
oXmlGravar.WriteAttributeString("nItem", detalhe.nItem.ToString());
objetoParaXML(oXmlGravar, detalhe.Prod, false);
oXmlGravar.WriteStartElement("imposto");
objetoParaXML(oXmlGravar, detalhe.Imposto.Icms, false);
objetoParaXML(oXmlGravar, detalhe.Imposto.Ii, false);
objetoParaXML(oXmlGravar, detalhe.Imposto.Ipi, false);
objetoParaXML(oXmlGravar, detalhe.Imposto.Pis, false);
objetoParaXML(oXmlGravar, detalhe.Imposto.Cofins, false);
oXmlGravar.WriteEndElement(); //fecha TAG imposto...
oXmlGravar.WriteEndElement(); //fecha TAG det...
}
objetoParaXML(oXmlGravar, infNFE.Total, false);
objetoParaXML(oXmlGravar, infNFE.Transp, false);
objetoParaXML(oXmlGravar, infNFE.Cobr, false);
objetoParaXML(oXmlGravar, infNFE.InfAdic, false);
oXmlGravar.WriteEndElement(); //fecha infNFe
oXmlGravar.WriteEndElement(); //fecha NFe
oXmlGravar.Flush();
xmlSaida.Flush();
xmlSaida.Position = 0;
XmlDocument documento = new XmlDocument();
documento.Load(xmlSaida);
oXmlGravar.Close();
return documento;
}
Função objetoParaXML, que gera o XML
private void objetoParaXML(XmlWriter xmlWriter, object objeto, bool ignorarDeclaracaoElemento)
{
if (objeto == null)
return;
Type tipoObjeto;
tipoObjeto = objeto.GetType();
PropertyInfo[] propriedades;
propriedades = tipoObjeto.GetProperties();
if (!ignorarDeclaracaoElemento)
xmlWriter.WriteStartElement(tipoObjeto.Name);
foreach (PropertyInfo propriedade in propriedades)
{
//A Função novaTag verifica se a propriedade em sí é um novo elemento, como o enderEmit
//no caso do emitente, e verifica tbm se esta propriedade foi declarada (!= null), se não ignora
if (Funcoes.novaTag(propriedade) && !(propriedade.GetValue(objeto, null) == null))
{
//utilizando recursão
objetoParaXML(xmlWriter, propriedade.GetValue(objeto, null), false);
continue;
}
object[] obj = propriedade.GetCustomAttributes(false);
Funcoes.gravarElemento(xmlWriter, propriedade.Name, propriedade.GetValue(objeto, null), obj);
}
if (!ignorarDeclaracaoElemento)
xmlWriter.WriteEndElement();
}
Bom, por enquanto é isso, não sei se consegui deixar claro sobre como funciona a classe, e agora estou com o tempo curto e vou postar assim mesmo, mas os comentários estão abertos para que todos possam perguntar, e assim vou melhorando este post e os códigos disponíveis.
Detalhe: A Classe está sendo disponibilizada gratuitamente, mas por favor, se você fizer alterações, notifique-me para que eu possa melhorar o código disponível.
Para usar, mude o código do button1, adicionando um CNPJ válido, IE, nome de empresa e etc.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Web Hosting Guide…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
muhabbet…
This is my Excerpt…
Recommeneded websites…
[...]Here are some of the sites we recommend for our visitors[...]……
Sites we Like……
[...] Every once in a while we choose blogs that we read. Listed below are the latest sites that we choose [...]……
Recommeneded websites…
[...]Here are some of the sites we recommend for our visitors[...]…
Websites worth visiting…
[...]here are some links to sites that we link to because we think they are worth visiting[...]…
Read was interesting, stay in touch…
[...]please visit the sites we follow, including this one, as it represents our picks from the web[...]…
Blogs ou should be reading…
[...]Here is a Great Blog You Might Find Interesting that we Encourage You[...]……
Websites worth visiting…
[...]here are some links to sites that we link to because we think they are worth visiting[...]……
Sites we Like……
[...] Every once in a while we choose blogs that we read. Listed below are the latest sites that we choose [...]……
Tumblr article…
I saw someone writing about this on Tumblr and it linked to…
Visitor recommendations…
[...]one of our visitors recently recommended the following website[...]……
Superb website…
[...]always a big fan of linking to bloggers that I love but don’t get a lot of link love from[...]……
News info…
I was reading the news and I saw this really cool info…
Informative and precise…
Its hard to find informative and accurate info but here I noted…
Its hard to find good help…
I am forever proclaiming that its difficult to get quality help, but here is …
African mango plus consumer reviews…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
Recent Blogroll Additions……
[...]usually posts some very interesting stuff like this. If you’re new to this site[...]……
Read was interesting, stay in touch……
[...]please visit the sites we follow, including this one, as it represents our picks from the web[...]……
Great website…
[...]we like to honor many other internet sites on the web, even if they aren’t linked to us, by linking to them. Under are some webpages worth checking out[...]……
Another Title…
I saw this really good post today….
Dreary Day…
It was a dreary day here today, so I just took to piddeling around online and realized…
News info…
I was reading the news and I saw this really interesting information…
Title…
homeowners insurance in florida…
You should check this out…
[...] Wonderful story, reckoned we could combine a few unrelated data, nevertheless really worth taking a look, whoa did one learn about Mid East has got more problerms as well [...]……
Gems form the internet…
[...]very few websites that happen to be detailed below, from our point of view are undoubtedly well worth checking out[...]……
Informative and precise…
Its hard to find informative and accurate information but here I found…
Visitor recommendations…
[...]one of our visitors recently recommended the following website[...]……
Recommeneded websites…
[...]Here are some of the sites we recommend for our visitors[...]……
Check this out…
[...] that is the end of this article. Here you’ll find some sites that we think you’ll appreciate, just click the links over[...]……
Recent Blogroll Additions……
[...]usually posts some very interesting stuff like this. If you’re new to this site[...]……
on acne…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
additional income stories,best funny short stories,guide bratty teenagers,eliminate childhood distractions,child literacy,eliminate bad behavior in teenagers,creative writing juices,friend proofing your tween,rushed parent,parenting guide,teenagers w…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
desenvolvimento sites|criar websites|desenvolvimento de websites|sites personalizados|desenvolvimento de websites profissionais|…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
Amazing Post!…
Thanks a lot for this amazing post. Really amazing!…
construção sites, loja virtual, comércio eletrônico, criação sites, construção site, desenvolvimento sites, marketing digital, otimização websites, empresa criação sites, criação websites, empresa criação sites, desenvolvimento websites…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
Flash Components, Site Templates, Flash Templates, Menus, Gallery, XML, Slideshow, FLV, Player, MP3, Player, Actionscript, AS1, AS2, AS3, android, gamez, appz, applications, soft, rom, custom, unique, pixels, envato, flashden, activeden, themeforest,…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
Links…
[...]Sites of interest we have a link to[...]……
[...]we like to honor many other internet sites on the web, even if they aren’t linked to us, by linking to them. Under are some webpages worth checking out[...]……
[...]Here are some of the sites we recommend for our visitors[...]……
Bored at work…
I like to browse in various places on the web, often I will go to Stumble Upon and read and check stuff out…
[...]Sites of interest we have a link to[...]……
[...]usually posts some very interesting stuff like this. If you’re new to this site[...]……
Get your Youtube Videos Seen!…
Find how here: http://lnkgt.com/7qq…
Read was interesting, stay in touch……
[...]please visit the sites we follow, including this one, as it represents our picks from the web[...]……
[...] that is the end of this article. Here you’ll find some sites that we think you’ll appreciate, just click the links over[...]……
[...] Every once in a while we choose blogs that we read. Listed below are the latest sites that we choose [...]… …
Wikia…
Wika linked to this site…
Cyst Acne…
[...]Geração de XML, validação e assinatura digital @ entendendo.net[...]…
Great website…
[...]we like to honor many other internet sites on the web, even if they aren’t linked to us, by linking to them. Under are some webpages worth checking out[...]……
Amazing Post!…
Thanks a lot for this amazing post. Really amazing!…
[...]we like to honor many other internet sites on the web, even if they aren’t linked to us, by linking to them. Under are some webpages worth checking out[...]……
[...]Here are some of the sites we recommend for our visitors[...]……
Amazing Post!…
Thanks a lot for this amazing post. Really amazing!…