Фреймворк Delphi DataSnap добавляет материал в сообщение JSON

Я работаю с REST-сервером Delphi XE DataSnap и пытаюсь вернуть сериализованный объект JSON. Результат, который мой метод возвращает клиенту, выглядит так:

{"type":"ServerMethodsUnit1.TJSONIssue",
 "id":1,
 "fields":{
           "FIssueNo":90210,
           "FTitle":"Beverly Hills...that''s where I want to be",
           "FKind":"Wishlist"
          }
}

Хорошо сформированный JSON.

Проблема в том, что когда сообщение получено клиентом, к нему добавляется куча всего, и оно выглядит так:

{"result": ["{\"type\":\"ServerMethodsUnit1.TJSONIssue\",
              \"id\":1,
              \"fields\":{
                          \"FIssueNo\":90210,
                          \"FTitle\":\"Beverly Hills...that's where I want to be\",
                          \"FKind\":\"Wishlist\"}
             }
            "
           ]
}

Я получаю кучу символов обратной косой черты и этот тег "result" впереди.

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


person Ron    schedule 28.01.2011    source источник
comment
Похоже, вы делаете двойной JSON? Управляющие символы (обратная косая черта) являются стандартными для строк JSON.   -  person Jørn E. Angeltveit    schedule 28.01.2011


Ответы (3)


Чтобы избавиться от тега "result", вы должны использовать событие OnFormatResult для TDSHTTPWebDispatcher. Особенно значение Handled. Значение Handled по умолчанию равно false. Если установлено значение true, то результат, переданный пользователю, не будет заключен в объект "result" JSON. Если оно ложно, то оно будет завернуто в этот объект.

Пример. У меня есть такой код:

function TServerMethods1.EchoStringJSON(Value: string): TJSONObject;
var
  JSONObj : TJSONObject;
begin
  JSONObj := TJSONObject.Create;
  JSONObj.AddPair(TJSONPair.Create('name',Value));
  result := JSONObj;
end;

Ответ службы REST выглядит так: {"result":[{"name":"asdfasdf"}]}

Добавляю Handled := true;:

procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject;
  var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
begin
  Handled := true;
end;

Ответ службы REST выглядит так: [{"name":"asdfasdf"}].

Еще есть "[]". Поэтому я добавляю дополнительный код:

procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject;
  var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
var
  Aux: TJSONValue;
begin
  //remove [] element
  Aux := ResultVal;
  ResultVal := TJSONArray(Aux).Items[0];
  TJSONArray(Aux).Remove(0);
  Aux.Free;
  //we do not need "result" tag
  Handled := true;
end;

Теперь результат выглядит так:{"name":"asdfasdf"}

PS. Ответ был найден здесь: раздел FormatResult Event for REST Responses .

person MyDogTom    schedule 26.05.2014

Опубликованный вами JSON представляет собой результат удаленного метода, который возвращает строку, а не JSONObject. Правильный способ возврата JSONObject должен быть следующим (не скомпилирован/не проверен):

function TMyRemote.GetSomething: TJSONValue;
begin
  Result := TJSONObject.Create;
  Result.Add("Name","Daniele Teti"); //used the overloaded version of add (string, string)
end;

Теперь json должен быть правильным. Элемент RESULT в строке результата соответствует задуманному. Вы можете прочитать первый элемент результирующего массива и получить исходный JSONObject.

person Daniele Teti    schedule 29.01.2011

Используете ли вы Delphi Desktop в качестве клиента? если да, возможно, вы можете попробовать другой возврат из вашего метода, потому что Delphi автоматически преобразует любой возвращаемый тип в JSON

например: возврат DBXReader будет преобразован в тип JSON

Если у вас есть другой клиент (php, java, flex), я не могу вам помочь. У меня та же проблема. Я создал метод для получения JSONObject в качестве параметра, и я сделал простой PHP-код для вызова этого метода... Я создал класс объекта и передал его... на сервере он не может преобразовать JSONObject в объект ... ошибка возникает при выполнении UnMarshall.

Мои тесты работают только с примитивными типами!

person Ricardo Pascoal    schedule 29.01.2011