'Error exporting data to JSON in Business Central

I am trying to export data to Json and having some trouble. When I run this I get error that says: The JSON object already contains the key 'Description'.

And the same error comes up with whatever line is run where I'm adding. Here is my code, can anyone see why it is happening...

codeunit 14135101 "ExportSalesToJson"
{
    procedure ExportSalesInvoiceAsJson(SalesInvoiceHeader: Record "Sales Invoice Header"; var JsonArr: JsonArray)

    var

        SalesLine: Record "Sales Invoice Line";
        SalesInvoiceHeaderJson: JsonObject;
        SalesLineArray: JsonArray;

        SalesIvoiceLineJson: JsonObject;
        SalesInvoiceLine: Record "Sales Invoice Line";


    begin

        SalesInvoiceHeaderJson.Add(SalesInvoiceHeader.FieldCaption("No."), SalesInvoiceHeader."No.");
        SalesInvoiceHeaderJson.Add(SalesInvoiceHeader.FieldCaption("Document Date"), SalesInvoiceHeader."Document Date");
        SalesInvoiceHeaderJson.Add(SalesInvoiceHeader.FieldCaption("Posting Date"), SalesInvoiceHeader."Posting Date");
        SalesInvoiceHeaderJson.Add(SalesInvoiceHeader.FieldCaption("Posting Description"), SalesInvoiceHeader."Posting Description");


        //SalesInvoiceLine.Reset();
        SalesInvoiceLine.SetRange("Document No.", SalesInvoiceHeader."No.");
        if SalesInvoiceLine.FindSet() then
            repeat

                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption("No."), SalesInvoiceLine."No.");
                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Description), SalesInvoiceLine.Description);
                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Type), Format(SalesInvoiceLine.Type));
                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption("Unit Price"), SalesInvoiceLine."Unit Price");
                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Amount), SalesInvoiceLine.Amount);
                SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Quantity), SalesInvoiceLine.Quantity);
                SalesLineArray.Add(SalesIvoiceLineJson);
            until SalesInvoiceLine.Next() = 0;
        SalesInvoiceHeaderJson.Add('Lines', SalesIvoiceLineJson);
        JsonArr.Add(SalesInvoiceHeaderJson);

    end;



    procedure ExportDocs()
    var
        SalesInvHeader: Record "Sales Invoice Header";
        JsonArr: JsonArray;
        Tempblob: Codeunit "Temp Blob";
        IStream: InStream;
        OStream: OutStream;
        ExportFileName: Text;
    begin
        SalesInvHeader.Reset();
        SalesInvHeader.FindSet();
        repeat
            ExportSalesInvoiceAsJson(SalesInvHeader, JsonArr);
        until SalesInvHeader.Next() = 0;

        Tempblob.CreateOutStream(OStream);

        IF JsonArr.WriteTo(OStream) THEN begin
            ExportFileName := 'Sales Invoices.json';
            Tempblob.CreateInStream(IStream);
            DownloadFromStream(IStream, '', '', '', ExportFileName);
        end;

    end;

Tried commenting out (specificly) the SalesInvoiceHeaderJson lines, but kept getting error.



Solution 1:[1]

You are reusing your SalesIvoiceLineJson variable without resetting it. This means that when your repeat statement runs the second time, the JsonObject will already contain the properties you are trying to add.

The best way to fix it would be to move the code within the repeat statement to a separate function with a local variable:

local procedure AddSalesInvoiceLine(SalesInvoiceLine: Record "Sales Invoice Line"; var SalesInvoiceLineArray: JsonArray)
var
    SalesIvoiceLineJson: JsonObject;
begin
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption("No."), SalesInvoiceLine."No.");
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Description), SalesInvoiceLine.Description);
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Type), Format(SalesInvoiceLine.Type));
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption("Unit Price"), SalesInvoiceLine."Unit Price");
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Amount), SalesInvoiceLine.Amount);
    SalesIvoiceLineJson.Add(SalesInvoiceLine.FieldCaption(Quantity), SalesInvoiceLine.Quantity);
    SalesInvoiceLineArray.Add(SalesIvoiceLineJson);
end;

And then call that function from the repeat statement.

Another solution would be to clear the SalesIvoiceLineJson at the beginning of the repeat statement:

Clear(SalesIvoiceLineJson);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kaspermoerch