#1 2018-02-01 17:30:15

keinn
Member
Registered: 2014-10-20
Posts: 103

so many days now,so frustrated ,please help.

after days of searching through the whole document and the forum, i am so frustrated.
still dont know how to send a binray file to mORMot server by the mORMot CrossPlatform Firemonkey restclient..
i need to send a picture taking form the camera to the server,
but i found out that the current  mORMot  Crossplatform Wrapper generated fmx client
can NOT process binary file sending ,
even if i try to tranform the fire to rawbinarystring or tbytes or base64 encoded , all failed. so sad.
seems that the crossplatform client only deal with the json type

the server side i tried the Method based Service approach ,the interface based service approach, the Ctxt.InputAsMutilPart approach,
when sending from the VCL mormot restclient ,all them works fine .
but on fmx mobile client , dont know how to do so .

please please please help.
nowadays, function like sending picture、video、audio files  form phone is really really really important.
thanks.

Offline

#2 2018-02-01 18:26:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: so many days now,so frustrated ,please help.

You don't need to use mime encoding between Delphi clients and servers.

Just use a method-based service, and, from a FireMonkey cross-platform service, call TSQLRestClientURI.URI with the appropriate URI/Verb/InBody parameters in TSQLRestURIParams:

    /// method calling the remote Server via a RESTful command
    // - calls the InternalURI abstract method
    // - this method will sign the url, if authentication is enabled
    procedure URI(var Call: TSQLRestURIParams); virtual;

Offline

#3 2018-02-01 20:08:28

keinn
Member
Registered: 2014-10-20
Posts: 103

Re: so many days now,so frustrated ,please help.

i tried this :

server side:

procedure TMyRestServer.UpFile(Ctxt: TSQLRestServerURIContext);
var
  FileName:TFileName;
begin
  FileName :=UTF8ToString(Int64ToUtf8(UnixMSTimeUTC));
  if Ctxt.Method = mPOST then
  begin
      FileFromString(Ctxt.Call.InBody,fFileFolder+FileName);
      Ctxt.Success;
  end else Ctxt.Error('',HTTP_NOTFOUND);

end;

fmx client side:

function TCrossRestHttpClient.SendBlobData(aFileName:TFileName):string;
var
  Call:TSQLRestURIParams;
  dummyID: integer;
  dataToSent :string;
begin
  Log(sllServiceCall,'Method-based service %s',['UpFile']);

 dataToSent :=UTF8FileToString(aFileName);
  Call.Init(getURICallBack('UpFile',nil,0),'POST',dataToSent);
  URI(Call);
  result := CallGetResult(Call,dummyID);

end;

but the file saved on serverside is incorrect,
go throuh all the SynCrossPlatform* functions can NOT find the right one to load a file to a rawbytestring.

Offline

#4 2018-02-01 20:15:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: so many days now,so frustrated ,please help.

Please define "incorrect".

Call.Init is for aUTF8Body text, not for binary - as the parameter name aUTF8Body states.

As I wrote above, try to set

Call.URI := getURICallBack('UpFile',nil,0);
Call.Verb := 'POST';
Call.InBody := ..... // fill the TBytes

and note that the THttpBody = TBytes is NOT a string.
Fill the TBytes from the file.

Offline

#5 2018-02-02 17:43:31

keinn
Member
Registered: 2014-10-20
Posts: 103

Re: so many days now,so frustrated ,please help.

Thank you very much!
i followed your guide ,
now all the Down/Upload work very good, both vcl and fmx, both method and interface based service works great!
thanks again.
a strange issue though:
when implemting interface based upload service

  ISendFile=interface(IInvokable)
  ['{F62C36A1-1A6A-401E-B6B6-457FEB6A7E3F}']
    function UploadPic(Pic:RawByteString):RawUTF8;
  end;

//i have to use the base64toBin to decode the incoming data

function TSendFileServiceImpl.UploadPic(Pic: RawByteString): RawUTF8;
var
  FileName,FilePath:TFileName;
begin
  Result :='0';
  FileName :=UTF8ToString(Int64ToUtf8(UnixMSTimeUTC));
  FilePath :=ExeVersion.ProgramFilePath+'File\'+FileName;
  if FileFromString(base64toBin(Pic),FilePath,true,Now())=True then

  Result :=StringToUTF8(FileName);
end;

//vcl client side had to use the BinToBase64
  i := Self.Service<ISendFile>;
  if i <> nil then
   Result := i.UploadPic(BinToBase64(Stringfromfile(PicFile)));

any way to avoid use the base64toBin /BinToBase64 funcs?

another thing ,

function CallGetResult(const aCall: TSQLRestURIParams; var outID: integer): variant;

this function above in the SynCrossPlatformRest.pas will you please make it accessable global?
since i have to set the Call my self in my class inherited from TSQLRestClientHTTP like TCrossRestHttpClient = class(TSQLRestClientHTTP)
dont wanna to modify the mORMot source ,otherwise is hard to sync from the git trunc

Offline

#6 2018-02-02 21:36:14

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: so many days now,so frustrated ,please help.

No, interface-based services expect base64 encoding for uploading information.

Use a method based service for uploading raw binary.

Offline

#7 2018-02-03 06:33:51

keinn
Member
Registered: 2014-10-20
Posts: 103

Re: so many days now,so frustrated ,please help.

i read about sending rawbinary with interface service somewhere in the forum or doc,

If your purpose is to upload some binary data, RawByteString and TSQLRawBlob input parameters will by default be transmitted as Base64 encoded JSON text.
You may define Client-Server services via methods to transmit raw binary, without the Base64 encoding overhead. It would allow low-access to the input content type and encoding, even with multi-part file upload from HTTP.
As an alternative, if you use default TSQLRestRoutingREST routing, and defined a single RawByteString or TSQLRawBlob input parameter, it will be processed as a raw POST with binary body defined with mime-type 'application/octet-stream'. This may be more optimized for remote access over the Internet.
See https://synopse.info/fossil/info/4cfc722c69

1、if it RawByteString or  TSQLRawBlob input param will be default translate to base64 encoded , why i still need i.UploadPic(BinToBase64(Stringfromfile(PicFile)));??

2、TSQLRestRoutingREST , how to set routing to enable raw binary trasport? cant find in the doc

Offline

#8 2018-02-03 11:12:56

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: so many days now,so frustrated ,please help.

You send the data encoded, so you need to decode it on the server side.

Plain Rawbytestring is to be used.

Offline

Board footer

Powered by FluxBB