You are not logged in.
Pages: 1
Hi
I'm trying to pass pure xml to interface based service with no success. It only works if xml is enclosed in brackets ["<?xml version="1.0" encoding="UTF-8" ?><notify>...</notify>"], otherwise it throws 406-bad input parameters.
Method is declared as follows:
function TNotifySrv.Test(aXml: UTF8String): UTF8String;
Test ajax request:
POST /notify/NotifySrv.Test HTTP/1.1
Host: xx.xx.xx.xx:8092
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: */*
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Length: 96
Content-Type: text/plain;charset=UTF-8
Origin: null
Connection: keep-alive
<?xml version="1.0" encoding="UTF-8" ?><notify>...</notify>
Regards, Tomek
Offline
XML is not handled as input from interface-based services.
It expects JSON content.
Either with brackets (one item per input argument), or as a JSON object (one field per argument).
See https://synopse.info/files/html/Synopse … #TITLE_448
To handle any kind of input, including a pure XML body, use a method-based service.
Offline
It expects JSON content.
Either with brackets (one item per input argument), or as a JSON object (one field per argument).
I've tried JSON object, but service received empty input
POST /notify/NotifySrv.Test HTTP/1.1
Host: xx.xx.xx.xx:8092
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: */*
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Length: 75
Content-Type: text/plain;charset=UTF-8
Origin: null
Connection: keep-alive
{"notify": {"event": "TEST", "timestamp": "1532530174.872"}, "alert": null}
Offline
Are you sure the JSON object matches the service input parameters?
Ensure you read https://synopse.info/files/html/Synopse … #TITLE_448
Offline
try this:
function TNotifySrv.Test(notify: UTF8String): UTF8String;
rename argument "aXml" to "notify".
Regards.
Esteban
Esteban
Offline
And try use RawJSON:
function TNotifySrv.Test(notify: RawJSON): UTF8String;
Offline
Ok, now I understand how matching parameters and JSON values works.
But it works only for flat JSON, eg:
{"notify": "event_test", "alert": null}
For nested JSON objects
{"notify": {"event": "TEST", "timestamp": "1532530174.872"}, "alert": null}
it throws 406: "INotifySrv.Test failed on notify:UTF8String [missing or invalid value]"
Is it possible to receive nested JSON objects?
Thx for all answers
Regards, Tomek
Offline
See RawJSON type of parameter in https://synopse.info/files/html/Synopse … l#TITL_154
Offline
Thx! now it works like charm
Btw: what is the easiest way to extract fields from simple JSON? (eg "event" from Notify example above)
I'm using TJSONTable, but is seems to "heavy" for this purpose.
Regards, Tomek
Offline
You can use e.g. a TDocVariant:
function TNotifySrv.Test(const notify, alert: variant): RawJSON;
var e: RawUTF8;
begin
e := notify.event; // it works!
end;
Or define a record:
type
TNotifyRec = packed record
event: RawUTF8;
timestamp: double;
end;
function TNotifySrv.Test(const notify: TNotifyRec; const alert: variant): RawJSON;
// and needed under oldest versions of Delphi or with FPC:
initialization
TJSONSerializer.RegisterCustomJSONSerializerFromText([
TypeInfo(TNotifyRec ), 'event:RawUTF8 timestamp:double']);
end.
Or use a TSynPersistent with published properties:
type
TNotifyObject = class(TSynPersistent)
...
published
property event: RawUTF8 read fEvent write fEvent;
property timestamp: double read fTimeSTamp write fTimeSTamp;
end;
function TNotifySrv.Test(const notify: TNotifyObject; const alert: variant): RawJSON;
Offline
You can use e.g. a TDocVariant:
function TNotifySrv.Test(const notify, alert: variant): RawJSON; var e: RawUTF8; begin e := notify.event; // it works! end;
It's a kind of magic
Thx once more.
Regards, Tomek
Offline
Variant is a magic, but without compile time checked and code insight. And it is quite slow.
Offline
Why slow?
TDocVariant is not so slow in practice, just a few nanoseconds slower than direct access.
For transmitted parameters, you can retrieve it once into a local variable, if you want to use it in a loop for instance.
Offline
Ok, I read this article http://blog.synopse.info/post/2011/07/0 … te-binding and now I know that mORMot has own late binding, and fast :-)
Offline
Pages: 1