Fórum Serialização XML - Classes de negócio #352
07/11/2008
0
Estou desenvolvendo uma aplicação semelhante a NF-E onde necessito serializar os dados em um arquivo XML.
Partindo do Schema XSD e utilizando o scrictp Xsd.exe do framework 2.0 gerei a classe de negócios para realizar a serialização.
Estou reproduzindo abaixo o trecho em que possuo duvidas.
Note que a Classe TEnviCTe possui uma propriedade do tipo TCTe[], ou seja, posso incluir diversos registros oriundos de um DataSet e posteriormente gerar o Xml com diversos registros.
O que não consigo fazer é preencher a coleção de objetos TCTe, apenas consigo gerar um a um dos registros, neste caso alterei a declaração para TCTe ao invés de TCTe[].
Preciso de um simples exemplo de um Laço que preencha varios objetos do tipo TCTe (propridade Cte) na classe TEnviCTe.
Codigo que uso para exportar um por um
TEnviCTe envCte = new TEnviCTe();
TCTe Cte = new TCTe();
// Prrencho aqui a classe CTe
envCte.CTe = Cte;
envCte.idLote = "Meu Id do Lote";
envCte.versao = "Minha Versão de Lote";
XmlSerializer xmlSer = new XmlSerializer(typeof(TCTe));
XmlTextWriter xtw = new XmlTextWriter(nomeArquivo, Encoding.UTF8);
xtw.Formatting = Formatting.Indented;
xtw.Indentation = 4;
xmlSer.Serialize(xtw,envCte)
Codigo da Classe
public partial class TEnviCTe {
private string idLoteField;
private TCTe[] cTeField;
private string versaoField;
[System.Xml.Serialization.XmlElementAttribute(DataType="token")]
public string idLote {
get {return this.idLoteField;}
set {this.idLoteField = value;}
}
[System.Xml.Serialization.XmlElementAttribute("CTe")]
public TCTe[] CTe {
get {return this.cTeField;}
set {this.cTeField = value;}
}
[System.Xml.Serialization.XmlAttributeAttribute(DataType="token")]
public string versao {
get {return this.versaoField;}
set {this.versaoField = value;}
}
}
public partial class TCTe {
private TCTeInfCte infCteField;
public TCTeInfCte infCte {
get {return this.infCteField;}
set {this.infCteField = value;}
}
}
Alessandro Pedroso
Curtir tópico
+ 0Posts
07/11/2008
Guinther Pauli
Troca de consultor: de Guinther Pauli para Carlos Junior
Gostei + 0
07/11/2008
[devmedia .net]
Gostei + 0
07/11/2008
[devmedia .net]
public TCTe[] CTe {
get {return this.cTeField;}
set {this.cTeField = value;}
} PARA : [System.Xml.Serialization.XmlArrayAttribute("CTe")]
public TCTe[] CTe {
get {return this.cTeField;}
set {this.cTeField = value;}
} OU [System.Xml.Serialization.XmlArrayItemAttribute("CTe")]
public TCTe[] CTe {
get {return this.cTeField;}
set {this.cTeField = value;}
} Aguardo retorno, Abraços Carlos Jr
Gostei + 0
10/11/2008
Alessandro Pedroso
Abaixo esta o XML
Creio que a minha duvida seja mais simples.
Note que tenho duas tags CTe e na minha classe tenho um campo que é TCTe[].
Eu preciso ler os dados de um dataset e preenche-lo na classe, mas não sei como preencher a propriedade CTe[], não sei como atribuir ou como instanciar, por exemplo:
foreach meuDataSet
{
CTe[i].infCte.id = id_do_Dataset;
}
Supondo que eu tenha cinco registros no meu dataset eu teria CTe[0], CTe[1], CTe[2], CTe[3], CTe[4] e cinco tags CTe no meu arquivo XML.
O codigo que faz a serialização esta funcionando corretamente quando estou usando apenas um registro, mas, aí altero a classe para TCTe ao invés de TCTe[], porque nao sei preencher o array de objetos.
[]s Alessandro Pedroso
<?xml version="1.0" encoding="utf-8"?>
<enviCTe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" versao="Minha Versão de Lote" xmlns="http://www.portalfiscal.inf.br/cte">
<idLote>Meu Id do Lote</idLote>
<CTe>
<infCte Id="Este é o meu ID" versao="Esta é a minha Versão">
<ide>
<cUF>43</cUF>
<cCT>12315646546</cCT>
<CFOP>987</CFOP>
<retira>0</retira>
<xDetRetira>È o detalhe do retira</xDetRetira>
</ide>
</infCte>
</CTe>
<CTe>
<infCte Id="Este é o meu ID Numero 2" versao="Esta é a minha Versão numero 2">
<ide>
<cUF>43</cUF>
<cCT>11</cCT>
<CFOP>345</CFOP>
<retira>0</retira>
<xDetRetira>È o detalhe do retira</xDetRetira>
</ide>
</infCte>
</CTe>
</enviCTe>
Gostei + 0
10/11/2008
[devmedia .net]
Gostei + 0
10/11/2008
[devmedia .net]
envCte.CTe[0] = Cte0; envCte.CTe[1] = Cte1; envCte.CTe[2] = Cte2; envCte.CTe[3] = Cte3;
envCte.idLote = "Meu Id do Lote";
envCte.versao = "Minha Versão de Lote"; Dessa maneira ele deve gerar corretamente os items que você deseja, mas no seu XML não estou vendo a propriedade que você quer repetir exatamente, pois o que está repetindo é apenas a própria classe. O que
Gostei + 0
10/11/2008
[devmedia .net]
envCte.CTe[0] = Cte0; envCte.CTe[1] = Cte1; envCte.CTe[2] = Cte2; envCte.CTe[3] = Cte3;
envCte.idLote = "Meu Id do Lote";
envCte.versao = "Minha Versão de Lote"; Dessa maneira ele deve gerar corretamente os items que você deseja, mas no seu XML não estou vendo a propriedade que você quer repetir exatamente, pois o que está repetindo é apenas a própria classe. O que eu
Gostei + 0
10/11/2008
[devmedia .net]
Gostei + 0
10/11/2008
Alessandro Pedroso
Carlos
Não posso usar o metodo WriteXML porque o XML é bastante complexo e extenso como voce pode notar abaixo. Dependendo de alguns parametros que recebo devo usar uma tag ou outra com campos totalmente diferentes.
Quanto ao item 2 , estou recebendo um NullReference na linha em vermelho, acho que estou cometendo alguma barbeiragem, segue o meu codigo.
Ressalto que este codigo so deixa de funcionar quando a classe esta declarada como um Array de objetos.
TEnviCTe envCte = new TEnviCTe();
TCTe Cte = new TCTe();
TCTeInfCte InfCte = new TCTeInfCte();
TCTeInfCteIde ide = new TCTeInfCteIde();
ide.cUF = TCodUfIBGE.Item43; // Código IBGE da UF do emitente do CTe
ide.cCT = "12315646546"; // Código numérico que compõe a chave de acesso. número aleatório gerado pelo emitente para cada CTe
ide.CFOP = "987"; // Código Fiscal de Operações e Prestações
ide.natOp = "4001"; // Descrição da Natureza da Operação
ide.forPag = TCTeInfCteIdeForPag.Item1; // Forma de pagamento de serviço; 0-Pago, 1-A pagar, 2-Outros
ide.mod = TModCT.Item57; // Código do modelo do CTe 57
ide.serie = "1"; // Série do CT
ide.nCT = "99852"; // Número do CT
ide.dhEmi = Convert.ToString(conhe.Dtemissao); // Data e hora da emissão do CTe
ide.tpImp = TCTeInfCteIdeTpImp.Item1; // Formato de impressão do DACTE (1-retrato, 2-paisagem)
ide.tpEmis = TCTeInfCteIdeTpEmis.Item1; // Forma de emissão do CTe (1-normal, 2-DANFE de contingência, emitida em formulário de segurança)
ide.cDV = "1"; // Digito verificador da chave de acesso da CTe
ide.tpAmb = TAmb.Item2; // Identificação do ambiente (1-produção,2-homologação)
ide.tpCTe = TFinCTe.Item0; // Finalidade da emissão do CTe (0-CTe normal, 1-CTe de complemento de valores, 2-CTe de anulação de valores (entrada), CTe substituto do CTe anulado)
ide.procEmi = TProcEmi.Item0; //
ide.verProc = "7.06";
ide.refCTE = ""; // Opcional
ide.cMunEmi = "00000";
ide.xMunEmi = "Porto Alegre";
ide.UFEmi = TUf.RS;
ide.modal = TModTransp.Item01;
ide.tpServ = TCTeInfCteIdeTpServ.Item0;
ide.cMunIni = "00000";
ide.xMunIni = "Porto Alegre";
ide.UFIni = TUf.RS;
ide.cMunFim = "05439";
ide.xMunFim = "Chui";
ide.UFFim = TUf.RS;
ide.xDetRetira = "È o detalhe do retira"; // opcional
InfCte.Id = "Este é o meu ID";
InfCte.versao = "Esta é a minha Versão";
InfCte.ide = ide;
Cte.infCte = InfCte;
envCte.idLote = "Meu Id do Lote";
envCte.versao = "Minha Versão de Lote";
envCte.CTe[0] = Cte;
SerializaConhecimento(typeof(TEnviCTe), envCte, "C:\\conhecimento.xml");
Gostei + 0
10/11/2008
[devmedia .net]
Gostei + 0
10/11/2008
Alessandro Pedroso
http://pub.sebastianswc.com/Cte.xml
Se quiser posso lhe enviar o xsd. Abaixo tambem vai uma imagem do layout.
Gostei + 0
10/11/2008
[devmedia .net]
Gostei + 0
10/11/2008
Alessandro Pedroso
Neste link tem a classe toda gerada pelo xsd, sem nenhuma modificação.
http://pub.sebastianswc.com/envicte.cs
So nao consigo preencher mais de uma propriedade do tipo TCTe[]
TEnviCTe envCte = new TEnviCTe(); //Classe do Root do XML
TCTe Cte = new TCTe(); // Cada linha do dataset preenche uma dimensão de objeto dessa classe
TCTeInfCte InfCte = new TCTeInfCte(); // esta classe esta dentro da classe cte e també é uma para cada linha do Data set
TCTeInfCteIde ide = new TCTeInfCteIde(); // Voce verá no XML as tags infcte e ide , tal qual a definição das classes.
Pequeno trecho da classe abaixo.
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.portalfiscal.inf.br/cte")]
[System.Xml.Serialization.XmlRootAttribute("enviCTe", Namespace = "http://www.portalfiscal.inf.br/cte", IsNullable = false)]
public partial class TEnviCTe
{
private string idLoteField;
private TCTe[] cTeField;
private string versaoField;
[System.Xml.Serialization.XmlElementAttribute(DataType = "token")]
public string idLote
{
get{return this.idLoteField;}
set{this.idLoteField = value;}
}
[System.Xml.Serialization.XmlArrayAttribute("CTe")]
public TCTe[] CTe
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
[System.Xml.Serialization.XmlAttributeAttribute(DataType = "token")]
public string versao
{
get{return this.versaoField;}
set{this.versaoField = value;}
}
}
}
Gostei + 0
10/11/2008
Alessandro Pedroso
public partial class TEnviCTe
{
private string idLoteField;
private TCTe[] cTeField; // este é que se repete ( e o que chamo de array)
private string versaoField;
[System.Xml.Serialization.XmlElementAttribute(DataType = "token")]
public string idLote
{
get{return this.idLoteField;}
set{this.idLoteField = value;}
}
[System.Xml.Serialization.XmlArrayAttribute("CTe")]
public TCTe[] CTe // este é que se repete ( e o que chamo de array)
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
Gostei + 0
10/11/2008
[devmedia .net]
public TCTe[] CTe {
get {
return this.cTeField;
}
set {
this.cTeField = value;
}
}
Ela aparece várias vezes, pois sendo uma classe ela é serializada automaticamente. No primeiro email que enviou vc diz que tem uma propriedade do tipo TCTe[], que é uma classe, portanto para popular essa propriedade você deverá instanciar a classe pai , popular os dados e atribuir essa classe à propriedade. Executando a serialização ela automaticamente será repetida, digo que o XML que enviou está correto. Vi que existe uma propriedade dentro do XML chamada tpCTe , não seria esse que vc quer repetir ? Abraços Carlos Jr
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)