2015-07-29 3 views
2

Я пытаюсь реализовать функцию, которая возвращает объект json, содержащий элементы класса. Вот моя функция:Build JSON with Delphi

procedure ListToJson(AInputList: TList<TRating>; 
    AResponse: TJSONObject); 
var 
    i: Integer; 
    jsonPair: TJSONPair; 
    jsonObject: TJSONObject; 
    jsonArray: TJSONArray; 
begin 
    jsonArray := TJSONArray.Create(); 
    jsonObject := TJSONObject.Create(); 
    jsonPair := TJSONPair.Create('ratings', jsonArray); 

    for i := 0 to AInputList.Count - 1 do 
    begin 
    jsonObject.AddPair(TJSONPair.Create('idrating', IntToStr(AInputList[i].IdRating))); 
    jsonObject.AddPair(TJSONPair.Create('idmark', IntToStr(AInputList[i].IdMark))); 
    jsonObject.AddPair(TJSONPair.Create('value', IntToStr(AInputList[i].Value))); 
    jsonObject.AddPair(TJSONPair.Create('description', AInputList[i].Description)); 
    jsonObject.AddPair(TJSONPair.Create('timeposted', FormatDateTime('yyyy-mm-dd hh:mm:ss', AInputList[i].TimePosted))); 

    jsonArray.AddElement(jsonObject); 
    end; 

    AResponse.AddPair(jsonPair); 
end; 

И когда я проверить его со списком, который содержит два элемента возвращаемой строки:

{ 
    "ratings":[{ 
     "idrating":"1", 
     "idmark":"0", 
     "value":"0", 
     "description":"", 
     "timeposted":"2015-07-29 11:25:03", 
     "idrating":"2", 
     "idmark":"0", 
     "value":"0", 
     "description":"", 
     "timeposted":"2015-07-29 11:25:24" 
    },{ 
     "idrating":"1", 
     "idmark":"0", 
     "value":"0", 
     "description":"", 
     "timeposted":"2015-07-29 11:25:03", 
     "idrating":"2", 
     "idmark":"0", 
     "value":"0", 
     "description":"", 
     "timeposted":"2015-07-29 11:25:24" 
    }] 
} 

Я попытался удалить все пары после каждой итерации цикла:

procedure ListToJson(AInputList: TList<TRating>; 
    AResponse: TJSONObject); 
var 
    i: Integer; 
    jsonPair: TJSONPair; 
    jsonObject: TJSONObject; 
    jsonArray: TJSONArray; 
begin 
    jsonArray := TJSONArray.Create(); 
    jsonObject := TJSONObject.Create(); 
    jsonPair := TJSONPair.Create('ratings', jsonArray); 

    for i := 0 to AInputList.Count - 1 do 
    begin 
    jsonObject.AddPair(TJSONPair.Create('idrating', IntToStr(AInputList[i].IdRating))); 
    jsonObject.AddPair(TJSONPair.Create('idmark', IntToStr(AInputList[i].IdMark))); 
    jsonObject.AddPair(TJSONPair.Create('value', IntToStr(AInputList[i].Value))); 
    jsonObject.AddPair(TJSONPair.Create('description', AInputList[i].Description)); 
    jsonObject.AddPair(TJSONPair.Create('timeposted', FormatDateTime('yyyy-mm-dd hh:mm:ss', AInputList[i].TimePosted))); 

    jsonArray.AddElement(jsonObject); 
    jsonObject.RemovePair('idrating'); 
    jsonObject.RemovePair('idmark'); 
    jsonObject.RemovePair('value'); 
    jsonObject.RemovePair('description'); 
    jsonObject.RemovePair('timeposted'); 
    end; 

    AResponse.AddPair(jsonPair); 
end; 

И Ouput является массив с п (количество элементов списка) пустые объекты: {"ratings":[{},{}]}

И я JSON пытаюсь построить должна быть как:

{ 
    "ratings":[{ 
    "idrating":"1", 
    "idmark":"0", 
    "value":"0", 
    "description":"", 
    "timeposted":"2015-07-29 11:25:03" 
    },{ 
    "idrating":"2", 
    "idmark":"0", 
    "value":"0", 
    "description":"", 
    "timeposted":"2015-07-29 11:25:24" 
    }] 
} 
+1

ли вам действительно нужно жестко кодировать создание этих пар? вы можете просто передать объект JSON-генератору и попросить его автоматически прочитать все свойства. http://stackoverflow.com/questions/7731833 –

ответ

5

У вас есть один jsonObject, поэтому любое состояние, в котором оно заканчивается, повторяется каждый раз, когда вы добавляете его в массив.

Построить jsonObject внутри цикла, а затем у вас будут разные объекты в вашем массиве.

for i := 0 to AInputList.Count - 1 do 
    begin 
    jsonObject := TJSONObject.Create(); 
    jsonObject.AddPair(TJSONPair.Create('idrating', IntToStr(AInputList[i].IdRating))); 
    jsonObject.AddPair(TJSONPair.Create('idmark', IntToStr(AInputList[i].IdMark))); 
    jsonObject.AddPair(TJSONPair.Create('value', IntToStr(AInputList[i].Value))); 
    jsonObject.AddPair(TJSONPair.Create('description', AInputList[i].Description)); 
    jsonObject.AddPair(TJSONPair.Create('timeposted', FormatDateTime('yyyy-mm-dd hh:mm:ss', AInputList[i].TimePosted))); 

    jsonArray.AddElement(jsonObject); 
    end; 

Alternatly, вы можете определить функцию для создания TJSONObject из TRating, и использовать это в цикле

function TRatingToJSON(Rating: TRating): TJSONObject; 
begin 
    Result := TJSONObject.Create(); 

    Result.AddPair(TJSONPair.Create('idrating', IntToStr(Rating.IdRating))); 
    Result.AddPair(TJSONPair.Create('idmark', IntToStr(Rating.IdMark))); 
    Result.AddPair(TJSONPair.Create('value', IntToStr(Rating.Value))); 
    Result.AddPair(TJSONPair.Create('description', Rating.Description)); 
    Result.AddPair(TJSONPair.Create('timeposted', FormatDateTime('yyyy-mm-dd hh:mm:ss', Rating.TimePosted))); 
end; 

procedure ListToJson(AInputList: TList<TRating>; 
    AResponse: TJSONObject); 
var 
    i: Integer; 
    jsonArray: TJSONArray; 
begin 
    jsonArray := TJSONArray.Create(); 

    for i := 0 to AInputList.Count - 1 do 
    begin 
    jsonArray.AddElement(TRatingToJSON(AInputList[i])); 
    end; 

    AResponse.AddPair(TJSONPair.Create('ratings', jsonArray)); 
end; 
0

Найдено workraround:

procedure ListToJson(AInputList: TList<TRating>; 
    AResponse: TJSONObject); 
var 
    i: Integer; 
    jsonPair: TJSONPair; 
    jsonObject: TList<TJSONObject>; 
    jsonArray: TJSONArray; 
begin 
    jsonArray := TJSONArray.Create(); 
    jsonObject := TList<TJSONObject>.Create; 
    jsonPair := TJSONPair.Create('ratings', jsonArray); 

    try 
    for i := 0 to AInputList.Count - 1 do 
    begin 
     jsonObject.Add(TJSONObject.Create()); 

     jsonObject.Last.AddPair(TJSONPair.Create('idrating', IntToStr(AInputList[i].IdRating))); 
     jsonObject.Last.AddPair(TJSONPair.Create('idmark', IntToStr(AInputList[i].IdMark))); 
     jsonObject.Last.AddPair(TJSONPair.Create('value', IntToStr(AInputList[i].Value))); 
     jsonObject.Last.AddPair(TJSONPair.Create('description', AInputList[i].Description)); 
     jsonObject.Last.AddPair(TJSONPair.Create('timeposted', FormatDateTime('yyyy-mm-dd hh:mm:ss', AInputList[i].TimePosted))); 

     jsonArray.AddElement(jsonObject.Last); 
    end; 

    AResponse.AddPair(jsonPair); 
finally 
    jsonObject.Free; 
end; 

конца;

+1

Приходит к рабочему результату, не понимая, что пошло не так, t объяснить себя – Caleth

2

Является ли это мне, или это просто очень некрасиво (и codous , или какое слово для большого количества кода для того, что он делает). Так как я на самом деле (на самом деле) не хочет видеть длинные списки перегрузок для всех видов типов, и на самом деле (на самом деле), как Variant типа, я создал jsonDoc, и это будет выглядеть следующим образом:

var 
    x:array of OleVariant; 
    i:integer; 
begin 
    SetLength(x,AInputList.Count); 
    for i:=0 to AInputListCount-1 do 
    x[i]:=JSON(
     ['idrating',AInputList[i].IdRating 
     ,'idmark',AInputList[i].IdMark 
     ,'value',AInputList[i].Value 
     ,'description',AInputList[i].Description 
     ,'timeposted',FormatDateTime('yyyy-mm-dd hh:mm:ss', AInputList[i].TimePosted)//VarFromDateTime? 
     ]); 
    end; 
    AResponse:=JSON(['ratings',VarArrayOf(x)]);