Post JSON data to RESTful datasnap server from delphi client
Asked Answered
P

3

2

I need to send a simple JSON object to a Restful datasnap server (Delphi) from a Delphi client. I am using Delphi XE. Can anybody help me out with the code? I am trying for hours but not getting it.. Please ask if details are not sufficient

Edit: Here is server side method declaration:

procedure updatemethodnme(str:string):string;

and here is client side code:

function PostData(request: string): boolean;
var
param: TStringList;
url, Text,str: string;
code: Integer;
http: TIDHttp;
begin
Result:= false;
http:= TIDHttp.Create(nil);
http.HandleRedirects:= true;
http.ReadTimeout:= 50000;
http.request.Connection:= 'keep-alive';
str:= '{"lamp":"'+lamp+'","floor":"'+floor+'","op":"'+request+'"}';
param:= TStringList.Create;
param.Clear;
param.Add(str);
url:= 'h***p://xx2.168.xx.xx:xxxx/Datasnap/rest/TserverMethods1/methdname/';
try
Text:= http.Post(url, param);
Result:= true;
except on E: Exception do
begin
Result := false;
end;
end;
end;
Plumcot answered 27/7, 2013 at 11:58 Comment(4)
Please take a moment to explain a little more detail about what problems you've been facing. Do you have some trial code you can post so we can see what you've tried?Gigahertz
So where do you get an error? Can you verify on the server that you actually receive something? Looking at the code I would say that it looks as if it should work.Buttons
Server is not receiving anything. on client side, sometimes its showing internal server error exception, n some time no error but nothing happens.Plumcot
You are posting the data using a TStringList but you need to post it using a TStream instead. Posting a TStringList creates a very different kind of HTTP request than posting a TStream, which affects how the server interprets and parses the request.Nickles
M
6

Here's some simple XE2 test code sending JSON data through HTTP Post using SuperObject (using Indy's TIdHTTP):

procedure TFrmTTWebserviceTester.Button1Click(Sender: TObject);
var
  lJSO : ISuperObject;
  lRequest: TStringStream;
  lResponse: String;
begin
  // Next 2 lines for Fiddler HTTP intercept:
  IdHTTP.ProxyParams.ProxyServer := '127.0.0.1';
  IdHTTP.ProxyParams.ProxyPort := 8888;
  lJSO := SO('{"name": "Henri Gourvest", "vip": true, "telephones": ["000000000", "111111111111"], "age": 33, "size": 1.83, "adresses": [ { "adress": "blabla", "city": "Metz", "pc": 57000 }, { "adress": "blabla", "city": "Nantes", "pc": 44000 } ]}');
  lRequest := TStringStream.Create(lJSO.AsString, TEncoding.UTF8);
  try
    IdHTTP.Request.ContentType := 'application/json';
    IdHTTP.Request.Charset := 'utf-8';
    try
      lResponse := IdHTTP.Post('http://127.0.0.1:8085/ttposttest', lRequest);
      ShowMessage(lResponse);
    except
      on E: Exception do
        ShowMessage('Error on request:'#13#10 + E.Message);
    end;
  finally
    lRequest.Free;
  end;
  lJSO := nil;
end;

This is the data that goes out:

POST http://127.0.0.1:8085/ttposttest HTTP/1.0
Content-Type: application/json; charset=utf-8
Content-Length: 204
Connection: keep-alive
Host: 127.0.0.1:8085
Accept: text/html, */*
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

{"vip":true,"age":33,"telephones":["000000000","111111111111"],"adresses":[{"adress":"blabla","pc":57000,"city":"Metz"},{"adress":"blabla","pc":44000,"city":"Nantes"}],"size":1.83,"name":"Henri Gourvest"}

Receiver is a TWebAction on a TWebModule, with handler:

procedure TWebModuleWebServices.WebModuleWebServicesTTPostTestAction(
  Sender: TObject; Request: TWebRequest; Response: TWebResponse;
  var Handled: Boolean);
var
  S   : String;
  lJSO: ISuperObject;
begin
  S := Request.Content;
  if S <> '' then
    lJSO := SO('{"result": "OK", "encodingtestcharacters": "Typed € with Alt-0128 Will be escaped to \u20ac"}')
  else
    lJSO := SO('{"result": "Error", "message": "No data received"}');
  Response.ContentType := 'application/json';  // Designating the encoding is somewhat redundant for JSON (https://mcmap.net/q/86913/-what-does-quot-content-type-application-json-charset-utf-8-quot-really-mean)
  Response.Charset := 'utf-8';
  Response.Content := lJSO.AsJSON;
  Handled := true;
end; { WebModuleWebServicesTTPostTestAction }

It uses TIdHTTPWebBrokerBridge:

FWebBrokerBridge := TIdHTTPWebBrokerBridge.Create(Self);
// Register web module class.
FWebBrokerBridge.RegisterWebModuleClass(TWebModuleWebServices);
// Settings:
FWebBrokerBridge.DefaultPort := 8085;        

This is the actual response:

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json; charset=utf-8
Content-Length: 92

{"encodingtestcharacters":"Typed\u20acwithAlt0128FollowedBy8364escaped\u8364","result":"OK"}
Myrmecology answered 29/7, 2013 at 6:24 Comment(2)
Hey.. thanx for the reply... Client side m able to send data using super object. but coming to server side, I want to use datasnap servermethods only. is there any way to do that?Plumcot
What do you mean by using ISuperObject? When you are using lJSO.AsString then that super object is useless.Claudiaclaudian
N
0

You can use Indy's TIdHTTP component to Post() JSON-encoded data to a REST server. You would simply have to encode and decode the JSON data in your own code.

Nickles answered 27/7, 2013 at 19:19 Comment(8)
I was going to mention exactly this, except that I'm unsure if the OP needs help with the Client, Server, or Both.Gigahertz
I thought it was very clear in his first sentence: "I need to send a simple JSON object to a Restful datasnap server (Delphi) from a Delphi client".Nickles
I understand that's the server-side which is being used, and there's also a client-side as well, both written in Delphi. I'm just not sure if the difficulties are related to the Client, Server, or Both.Gigahertz
Are you joking? It's clear that he is trying to write a client that needs to post to a server.Nickles
I've tried with indy idhttp component already.. actually m not getting hw to encode json data in client side. earlier I sent a string & an integer by idhttp n it worked... but no idea how to deal with jsonPlumcot
@achievelimitless The the issue is with serializing JSON data?Gigahertz
@achievelimitless: put the JSON data into a TStringStream or TMemoryStream and then Post() that. You will likely need to set the TIdHTTP.Request.ContentType to 'application/json', and maybe the TIdHTTP.Request.Charset as well.Nickles
@achievelimitless: you are posting the JSON data using a TStringList, which is wrong. You have to use a TStream instead, like I mentioned earlier. Posting a TStringList creates a very different kind of HTTP request body than posting a TStream.Nickles
G
0

From Delphi6 posting to a datasnap server built in XE5 the above works for me, but I had found out the server method needed the parameter to be defined as a TJSONObject instead of TStream. Something odd in addition to this, the Datansap server changes the lookup method when you do a post instead of a get. For example I had a method named ImportData. But when you debug the server it was looking for an UpdateImportData method. So when I added the new method and changed the parameter type to Data.DBXJSON.TJSONObject it worked.

Gerardogeratology answered 28/9, 2018 at 11:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.