Fórum Serialização XML - Classes de negócio #352

07/11/2008

0

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;}
    }
}
Alessandro Pedroso

Alessandro Pedroso

Responder

Posts

07/11/2008

Guinther Pauli

mensagem gerada automaticamente pelo sistema

Troca de consultor: de Guinther Pauli para Carlos Junior
Responder

Gostei + 0

07/11/2008

[devmedia .net]

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
Responder

Gostei + 0

07/11/2008

[devmedia .net]

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
Responder

Gostei + 0

10/11/2008

Alessandro Pedroso

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>
Responder

Gostei + 0

10/11/2008

[devmedia .net]

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
Responder

Gostei + 0

10/11/2008

[devmedia .net]

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  
Responder

Gostei + 0

10/11/2008

[devmedia .net]

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  
Responder

Gostei + 0

10/11/2008

[devmedia .net]

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
Responder

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");


Responder

Gostei + 0

10/11/2008

[devmedia .net]

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
Responder

Gostei + 0

10/11/2008

Alessandro Pedroso

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.



Responder

Gostei + 0

10/11/2008

[devmedia .net]

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
Responder

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;}
        }
    }
}


Responder

Gostei + 0

10/11/2008

Alessandro Pedroso

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;}
        }
Responder

Gostei + 0

10/11/2008

[devmedia .net]

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    
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar