Converter Json para objeto
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)
Converte Json para ACBrCTe (Erro)
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
Curtidas 0
Respostas
Joel Rodrigues
05/02/2013
Em que linha ocorre o erro?
GOSTEI 0
Bruno Leandro
05/02/2013
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;
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;
GOSTEI 0
Gustavo Cruz
05/02/2013
Então Joel o erro ocorre na função JSONToACBrCTe linha:
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:
Estou usando o Delphi 2010 Update 3
Fiz um projeto com o exemplo do erro segue o código:
Obrigado pela atenção de todos.
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.
GOSTEI 0