Converter Json para objeto

05/02/2013

0

Sei que para converter objetos em Json utilizamos o TJSONMarshal e para fazer o inverso utilizamos o TJSONUnMarshal.
Tudo isso funciona até os objetos começarem a ficar mais complexos em sua estrutura...
Ao converter um objeto TACBrCTe para Json tudo bem, mas quando tento retornar o objeto utilizando o método TJSONUnMarshal retorna um "access violation".

Meu código:
Converte ACBrCTe para Json (Funciona)
function ACBrCTeToJSON(ACBrCTe: TACBrCTe): TJSONValue;
var
  m: TJSONMarshal;
begin
  if Assigned(ACBrCTe) then
  begin
    m := TJSONMarshal.Create(TJSONConverter.Create);

    try
      Result := m.Marshal(ACBrCTe);
      Exit;
    finally
      m.Free;
    end;
  end
  else
  begin
    Result := TJSONNull.Create;
    Exit;
  end;
end;


Converte Json para ACBrCTe (Erro)
function JSONToACBrCTe(json: TJSONValue): TACBrCTe;
var
   unm: TJSONUnMarshal;
begin
  if json is TJSONNull then
  begin
    Result := nil;
    Exit;
  end;

  unm := TJSONUnMarshal.Create;

  try
    Result := TACBrCTe(unm.Unmarshal(json));
    Exit;
  finally
    unm.Free;
  end;
end;
Gustavo Cruz

Gustavo Cruz

Responder

Posts

05/02/2013

Joel Rodrigues

Em que linha ocorre o erro?
Responder

06/02/2013

Bruno Leandro

Ola Gustavo eu dei uma olhada e sem debugar talvez o erro seja ao atribuir um valor ao result, tente desta forma

function JSONToACBrCTe(json: TJSONValue): TACBrCTe;
var
unm: TJSONUnMarshal;
begin
Result := TACBrCTe.Create;
if json is TJSONNull then
begin
Result := nil;
Exit;
end;

unm := TJSONUnMarshal.Create;

try
Result := TACBrCTe(unm.Unmarshal(json));
Exit;
finally
unm.Free;
end;
end;
Responder

14/02/2013

Gustavo Cruz

Então Joel o erro ocorre na função JSONToACBrCTe linha:
Result := TACBrCTe(unm.Unmarshal(json));


Bruno, mesmo colocando Result := TACBrCTe.Create; o erro continua.

O erro retornado é :
"Assertion failure (c:\arquivos de programas\embarcadero\rad studio\7.0\source\database\DBXJSONReflect.pas, line 1456)"
A pas informada no erro pertence ao JSON e a linha 1456 é a seguinte:

assert(JsonObj.Get(1).JsonString.Value=ID_NAME);


Estou usando o Delphi 2010 Update 3

Fiz um projeto com o exemplo do erro segue o código:

unit Principal;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,

  ACBrCTe,DBXJSON,DBXJSONReflect,pcnConversao, StdCtrls, Buttons;

type
  TfrmPrincipal = class(TForm)
    Label7: TLabel;
    edArqXml: TEdit;
    btnPasta: TBitBtn;
    OpenDialog1: TOpenDialog;
    ACBrCTe1: TACBrCTe;
    ACBrCTe2: TACBrCTe;
    procedure btnPastaClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    function ACBrCTeToJSON(ACBrCTe: TACBrCTe): TJSONValue;
    function JSONToACBrCTe(json: TJSONValue): TACBrCTe;
    procedure GetACBrCTe ( ACBrCTe:TJSONValue);
  public
    { Public declarations }
  end;

var
  frmPrincipal: TfrmPrincipal;

implementation

{$R *.dfm}

procedure TfrmPrincipal.btnPastaClick(Sender: TObject);
begin
  //Configuro para filtrar apenas arquivos xmls
  OpenDialog1.Title      := 'Selecione o CTe';
  OpenDialog1.DefaultExt := '*.xml';
  OpenDialog1.Filter     := 'Arquivos CTe (*.xml)|*.xml|Arquivos XML (*.xml)|*.xml|Todos os Arquivos (*.*)|*.*';

  if OpenDialog1.Execute then
  begin
    //limpo os conhecimentos
    ACBrCTe1.Conhecimentos.Clear;
    //pego o conhecimento (xml) selecionado
    ACBrCTe1.Conhecimentos.LoadFromFile(OpenDialog1.FileName);
    //Envio o CTe convertendo o objeto ACBrCTe em JSON, para a procedure validar o xml
    GetACBrCTe(ACBrCTeToJSON(ACBrCTe1));
  end;
end;

procedure TfrmPrincipal.FormCreate(Sender: TObject);
var
  Ok         : Boolean;
begin
  ACBrCTe1.Configuracoes.Certificados.NumeroSerie  := 'numero do certificado digital';

    //['1', '2', '3', '4', '5', '6', '7', '8', '9'],
    //[teNormal, teContingencia, teSCAN, teDPEC, teFSDA, teSVCAN, teSVCRS, teSVCSP, teOffLine]);

    ACBrCTe1.Configuracoes.Geral.FormaEmissao := StrToTpEmis( OK,IntToStr( 1 ) );
    ACBrCTe1.Configuracoes.Geral.Salvar       := True;
    ACBrCTe1.Configuracoes.WebServices.UF     := 'SP';

    //TpcnTipoAmbiente = (taProducao, taHomologacao);
    ACBrCTe1.Configuracoes.WebServices.Ambiente   := StrToTpAmb( Ok,IntToStr( 1 ) );
    ACBrCTe1.Configuracoes.WebServices.Visualizar := False;
end;

procedure TfrmPrincipal.GetACBrCTe(ACBrCTe: TJSONValue);
begin
  //Recebo o CTe no formato JSON e converto para ACBrCTe
  ACBrCTe2 := JSONToACBrCTe(ACBrCTe);
  //Valido o XML
  ACBrCTe2.Conhecimentos.Valida;
end;

//Converte JSON para ACBrCTe
function TfrmPrincipal.JSONToACBrCTe(json: TJSONValue): TACBrCTe;
var
   unm: TJSONUnMarshal;
begin
  Result := TACBrCTe.Create(nil);

  if json is TJSONNull then
  begin
    Result := nil;
    Exit;
  end;

  unm := TJSONUnMarshal.Create;

  try
    //Ao efetuar o cast retorna o erro :
    //Assertion failure (c:\arquivos de programas\embarcadero\rad studio\7.0\source\database\DBXJSONReflect.pas, line 1456)
    Result := TACBrCTe(unm.Unmarshal(json));
    Exit;
  finally
    unm.Free;
  end;
end;

//Converte ACBrCTe para JSON
function TfrmPrincipal.ACBrCTeToJSON(ACBrCTe: TACBrCTe): TJSONValue;
var
  m: TJSONMarshal;
begin
  if Assigned(ACBrCTe) then
  begin
    m := TJSONMarshal.Create(TJSONConverter.Create);

    try
      Result := m.Marshal(ACBrCTe);
      Exit;
    finally
      m.Free;
    end;
  end
  else
  begin
    Result := TJSONNull.Create;
    Exit;
  end;
end;

end.



Obrigado pela atenção de todos.
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

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

Aceitar