Delphi DataSnap framework adding stuff to JSON mes

2020-06-18 01:57发布

问题:

I'm working with a Delphi XE DataSnap REST server and trying to return a JSON serialized object. The result that my method is returning to the client looks like this:

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

Well formed JSON.

The problem is that when the message is received by the client, there's a bunch of stuff added to it and it looks like this:

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

I'm getting a bunch of backslash characters and that "result" tag in front.

I was wondering if anybody knows why I'm getting this extra stuff and how to get rid of it.

回答1:

To get rid of "result" tag you should use OnFormatResult event of TDSHTTPWebDispatcher. Especialy the value Handled. The value of Handled is false by default. If set to true, then the result passed to the user will not be wrapped in a "result" JSON object. If it is false, then it will be wrapped in this object.

Example. I have code like this:

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

REST service response looks like this: {"result":[{"name":"asdfasdf"}]}

I add Handled := true;:

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

REST service response looks like this:[{"name":"asdfasdf"}].

Still have "[]". So I add some additional code:

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;

Now result looks like:{"name":"asdfasdf"}

PS. The answer was found here: section FormatResult Event for REST Responses.



回答2:

The JSON that you have posted rapresent a result for a remote method that returns a string, not a JSONObject. The correct way to return a JSONObject should be the following (not compiled/tested):

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

Now the json should be correct. The RESULT element in the result string is as-designed. You can read the first element of the result array and get your original JSONObject.



回答3:

Are you using a Delphi Desktop as a client ? if Yes maybe you can try other return from your method because Delphi make a automatically conversion of any return type to JSON

for example : return a DBXReader will be converted to a JSON Type

In case you have other Client (php, java, flex) I cant to help you. I have the same problem ..I created a method to receive a JSONObject as parameter and I did a simples PHP code to invoke this method... I created a object class and pass it ..in the server it cant convert JSONObject to Object ...the error happens when UnMarshall execute..

My tests just work with primitive types !