Serialização XML - Classes de negócio
Srs
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;}
}
}
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
Curtidas 0
Respostas
Guinther Pauli
07/11/2008
mensagem gerada automaticamente pelo sistema
Troca de consultor: de Guinther Pauli para Carlos Junior
Troca de consultor: de Guinther Pauli para Carlos Junior
GOSTEI 0
[devmedia .net]
07/11/2008
Opa, blz Alessandro ?
Seguinte, para que eu possa entender melhor seu problema,
teria como me enviar como seria o correto XML a ser gerado ??
Pelo que entendi você deseja colocar mais de um item na propriedade no momento da serialização é isso mesmo ?
Abraços
Carlos Jr
GOSTEI 0
[devmedia .net]
07/11/2008
Alessandro,
modifique a propriedade marcada abaixo
DE:
[System.Xml.Serialization.XmlElementAttribute("CTe")]
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
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
Alessandro Pedroso
07/11/2008
Bom dia Carlos
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>
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
[devmedia .net]
07/11/2008
Opa, blz Alessandro ?
Você tentou modificar as propriedades da maneira que eu citei ?
Caso não tenha feito, faça para testarmos.
Realmente para fazer o que vc deseja não tem segredo,
deveria estar funcionando.
Vou fazer um teste aqui e lhe retorno, aguarde um momento por favor.
Abraços
Carlos Jr
GOSTEI 0
[devmedia .net]
07/11/2008
Alessandro,
vou lhe fazer algumas perguntas...
1- Por quê não utiliza o método WriteXml do dataset para gerar o seu XML ?
2- Para que seja gerado vários items no XML dentro de CTe, este deve ser atribuido várias vezes para esse objeto.
// Prrencho aqui a classe CTe
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
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
[devmedia .net]
07/11/2008
Alessandro,
vou lhe fazer algumas perguntas...
1- Por quê não utiliza o método WriteXml do dataset para gerar o seu XML ?
2- Para que seja gerado vários items no XML dentro de CTe, este deve ser atribuido várias vezes para esse objeto.
// Prrencho aqui a classe CTe
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
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
[devmedia .net]
07/11/2008
Continuando (sem querer enviei a mensagem)...
O que eu te pedi foi o XML que você deseja que seja gerado, vamos dizer o XML correto, ok !?
Pois a partir dele conseguirei mapear melhor sua dúvida.
Abraços
Carlos Jr
GOSTEI 0
Alessandro Pedroso
07/11/2008
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
[devmedia .net]
07/11/2008
Opa, ok entendido !
Pode me enviar os códigos das classes envolvidas para que eu possa simular o seu ambiente aqui ?
Assim eu teria mais controle e poderia lhe dar uma resposta mais rápdia.
Sobre o erro abaixo:
Está ocorrendo pois você não inicializou as classes que estão contidas no array, por esse motivo dá esse erro.
No aguardo.
Carlos Jr
GOSTEI 0
Alessandro Pedroso
07/11/2008
Segue link para o XML e imagem
http://pub.sebastianswc.com/Cte.xml
Se quiser posso lhe enviar o xsd. Abaixo tambem vai uma imagem do layout.
http://pub.sebastianswc.com/Cte.xml
Se quiser posso lhe enviar o xsd. Abaixo tambem vai uma imagem do layout.
GOSTEI 0
[devmedia .net]
07/11/2008
Alessandro,
qual a propriedade da classe que você quer que repita ?
Ainda não identifiquei isso...
Qual a propriedade que deve se repetir ?
Pois o que eu vejo repetindo no XML é apenas a classe...
A propriedade que você a colocou como array não a vejo !
no aguardo.
Pode estar um pouco confuso pelo fato de você estar em contato com o sistema e eu não tenho o mesmo contato, portanto pode estar deixando de passar alguma informação que para você seja óbvia, mas para mim não !
Falou
Abraços
GOSTEI 0
Alessandro Pedroso
07/11/2008
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
Alessandro Pedroso
07/11/2008
Perdão, acho que estou me expressando errado, não é um array, acho que isso é uma collection, veja os itens em vermelho
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;}
}
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
[devmedia .net]
07/11/2008
Alessandro,
pelo xml que enviou a classe Cte já está sendo repetida com todas a suas propriedades dentro dela...
[System.Xml.Serialization.XmlElementAttribute("CTe")]
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
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
[devmedia .net]
07/11/2008
Alessandro,
Acho que achei a solução disso..
Lhe envio hoje mais tarde, vou fazer o exemplo aqui e lhe envio.
Ok !?
Abraços
Carlos Jr
GOSTEI 0
[devmedia .net]
07/11/2008
Alessandro,
Por favor me responda as perguntas abaixo para que eu finalize meus testes,
pelo xml que enviou a classe Cte já está sendo repetida com todas a suas propriedades dentro dela...
[System.Xml.Serialization.XmlElementAttribute("CTe")]
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
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
Alessandro Pedroso
07/11/2008
Carlos
Aquele XML é o meu exemplo, tem que sair como esta nele, eu gerei varias repetições manualmente.
Na verdade nao consigo repeti-la pois , nao consigo repetir a classe CTe.
Entao vejamos, tenho a classe pai que é a TEnviCTe e dentro dela vou ter diversas TCTe que estao expostas pela propriedade CTe conforme abaixo
public partial class TEnviCTe
{
private string idLoteField;
private TCTe[] cTeField; // este é a classe TCTe
private string versaoField;
// Como fazer para repetir varias vezes esta propriedade
public TCTe[] CTe // este é que se repete
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
Então a minha duvida é como fazer para atribuir varias vezes a propriedade CTe dentro da classe pai que TEnviCTe.
Imagino algo como
TEnviCTe ect = new TEnviCTe();
//primeira atribuição
ect.Cte[0].campo = 1;
//segunda repetição
ect.Cte[1].campo = 2;
O problema é que recebo um null reference se fizer assim, mas se eu mudar a declaração para
public TCTe CTe // removi os colchetes
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
aí eu consigo preencher normalmente sem nenhum erro.
Creio que isto seja uma coisa simples, apenas não consigo encontrar a forma de atribuir a propriedade varias vezes como eu preciso, para que a CTe se repita varias vezes no XML.
Portanto para popular essa propriedade você deverá instanciar a classe pai , popular os dados e atribuir essa classe à propriedade.
E como eu faço isso, acho que essa é a minha duvida. Pode me dar um exemplo?
[]s Alessandro Pedroso
Aquele XML é o meu exemplo, tem que sair como esta nele, eu gerei varias repetições manualmente.
Na verdade nao consigo repeti-la pois , nao consigo repetir a classe CTe.
Entao vejamos, tenho a classe pai que é a TEnviCTe e dentro dela vou ter diversas TCTe que estao expostas pela propriedade CTe conforme abaixo
public partial class TEnviCTe
{
private string idLoteField;
private TCTe[] cTeField; // este é a classe TCTe
private string versaoField;
// Como fazer para repetir varias vezes esta propriedade
public TCTe[] CTe // este é que se repete
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
Então a minha duvida é como fazer para atribuir varias vezes a propriedade CTe dentro da classe pai que TEnviCTe.
Imagino algo como
TEnviCTe ect = new TEnviCTe();
//primeira atribuição
ect.Cte[0].campo = 1;
//segunda repetição
ect.Cte[1].campo = 2;
O problema é que recebo um null reference se fizer assim, mas se eu mudar a declaração para
public TCTe CTe // removi os colchetes
{
get{return this.cTeField;}
set{this.cTeField = value;}
}
aí eu consigo preencher normalmente sem nenhum erro.
Creio que isto seja uma coisa simples, apenas não consigo encontrar a forma de atribuir a propriedade varias vezes como eu preciso, para que a CTe se repita varias vezes no XML.
Portanto para popular essa propriedade você deverá instanciar a classe pai , popular os dados e atribuir essa classe à propriedade.
E como eu faço isso, acho que essa é a minha duvida. Pode me dar um exemplo?
[]s Alessandro Pedroso
GOSTEI 0
[devmedia .net]
07/11/2008
Alessandro,
fiz alguns testes e tudo funcionou perfeitamente...
Você deverá alterar suas classes para utilizarem Generics,
que é muito melhor de trabalhar do que os arrays (que nada mais são que arrays "tipados").
Bom, da maneira que demonstro abaixo funciona corretamente, e vc deverá instanciar suas classes e inicializá-las com os objetos que vc deseja serializar, inclusive criei uma classe para fazer essa tarefa, separando o método de serializar e deserializar.
Segue.
Classe Cliente
using System;
using System.Collections.Generic;
using System.Text;
[Serializable]
public class Cliente
{
private string _codigoCliente;
private string _nomeCliente;
private List<Telefone> _telefoneCliente;
public string CodigoCliente
{
get { return _codigoCliente; }
set { _codigoCliente = value; }
}
public string NomeCliente
{
get { return _nomeCliente; }
set { _nomeCliente = value; }
}
public List<Telefone> TelefoneCliente
{
get { return _telefoneCliente; }
set { _telefoneCliente = value; }
}
//As classes a serem serializadas deve ter um construtor vazio, sem parâmetros
public Cliente()
{ }
public Cliente(string codigoCliente, string nomeCliente)
{
this._codigoCliente = codigoCliente;
this._nomeCliente = nomeCliente;
}
}
Classe Telefone
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
[Serializable]
public class Telefone
{
private string _numTelefone;
public string NumTelefone
{
get { return _numTelefone; }
set { _numTelefone = value; }
}
//As classes a serem serializadas deve ter um construtor vazio, sem parâmetros
public Telefone()
{ }
public Telefone(string NumTelefone)
{
this._numTelefone = NumTelefone;
}
}
Classe Serializador
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
public class Serializador
{
public static string Serializar(object algumObjeto)
{
StringWriter writer = new StringWriter();
XmlSerializer serializer = new XmlSerializer(algumObjeto.GetType());
serializer.Serialize(writer, algumObjeto);
return writer.ToString();
}
public static object Deserializar(string xml, Type type)
{
StringReader reader = new StringReader(xml);
XmlSerializer serializer = new XmlSerializer(type);
return serializer.Deserialize(reader);
}
}
Chamada das classes na página principal
protected void Page_Load(object sender, EventArgs e)
{
// Serialização
List<Telefone> telefoneCliente = new List<Telefone>();
//Chama o construtor da classe
Cliente cliente = new Cliente("0001", "Mariana");
//Momento em que se adicona o telefone do cliente
//Estou fazendo passo a passo para você entender melhor
//Adiciona um objeto pelo Generics e
//Chama o construtor da classe
telefoneCliente.Add(new Telefone("123456789"));
telefoneCliente.Add(new Telefone("987654321"));
telefoneCliente.Add(new Telefone("000000000"));
cliente.TelefoneCliente = telefoneCliente;
string xml = Serializador.Serializar(cliente);
Console.WriteLine(xml);
// Deserialização
Cliente clienteDeserializado = Serializador.Deserializar(xml, typeof(Cliente)) as Cliente;
Console.WriteLine("Codigo: \t Nome: ", clienteDeserializado.CodigoCliente, clienteDeserializado.NomeCliente);
Console.ReadLine();
}
Se criar um projeto e criar essas classes, verá que funciona perfeitamente,
adapte ao seu projeto e funcionará certinho.
Aguardo seu retorno.
Abraços
Carlos Jr
GOSTEI 0
[devmedia .net]
07/11/2008
Aplique o exemplo que eu enviei acima para você, vai funcionar com certeza..
O problema de utilizar da maneira como está com o array, não vai ficar legal..
você deve adicionar um número de objeto de uma vez, sabendo que vc não sabe quantos registros serão retornados, o array vai ficar redimensionando a todo momento, e isso não é bom para a aplicação,
pois array não tem um tipo específico e nesse caso ocupará muita memória comprometendo sua aplicação.
O uso do Generics é justamente para termos essa solução,
você verá que precisará alterar apenas o atributo que quer repetir na sua aplicação..
Colocando como..
Depois adiciona os itens...
Cte itemCte = new Cte();
List<Cte> xCte = new List<Cte>();
itemCte.campo = 1;
xCte.Add(itemCte);
itemCte = new Cte();
itemCte.campo = 2;
xCte.Add(itemCte);
Sacou !?
Mas dentro da classe pai deve ter o atributo do mesmo tipo.
Se tiver dificuldade me avise, vamos resolver seu problema o quanto antes.
Abraços
GOSTEI 0
Alessandro Pedroso
07/11/2008
Blz
Funcionou perfeitamente.
Da um desconto que meu curso foi em Framework 1 que não tem o generics.
Foi mais dificil explicar do que resolver.
Obrigado, ficou 10!!
Funcionou perfeitamente.
Da um desconto que meu curso foi em Framework 1 que não tem o generics.
Foi mais dificil explicar do que resolver.
Obrigado, ficou 10!!
GOSTEI 0