Upload file to DataSnap REST server via TStream

Hi,

I've built a DataSnap REST server using Delphi XE2 and I've added a server method for uploading files via TStream :
{code}function TServerMethods.updateUploadFile(sFilename: string; UploadStream: TStream): string;{code}
I want to be able to call this from a number of different clients (Android, iOS etc) and I've been testing the method using various REST clients such as Postman (Chrome plugin).  However so far I cannot get it to accept the content for the HTTP POST body.  Whenever I send the HTTP POST command I always get the following response :
{code}{"error":"Message content is not a valid JSON value."}{code}
I've tried using various different 'Content-Type' settings but nothing seems to work.  It looks as though DataSnap is insisting on the content being JSON?  I've tried pasting some valid JSON into the content area but this also gave the same error response.

Has anybody successfully used TStream as an input parameter for a DataSnap server method?  Should I be doing it another way?  I've used TStream as an output parameter for downloading files many times and it works well, this is my first attempt at uploading files.

Thanks,
Jonathan
0
Jonathan
8/7/2013 6:18:21 PM
embarcadero.datasnap 643 articles. 1 followers. Follow

7 Replies
5223 Views

Similar Articles

[PageSpeed] 7

*UPDATE*

I made a quick Delphi DataSnap client to test the uploadFile server method and this all works great.  I then used Fiddler to examine the POST command the Delphi client uses to send the TStream in the content body, and noticed it is a JSON array of integers (bytes) e.g. {code}[37,80,68,70,45,49,46,51,13,10]{code}So I can see that I could modify my Android/iOS clients to convert the binary data to this byte array format before POSTing, but this is an overhead I could do without.  If DataSnap streams raw bin
ary when TStream is a return parameter, why can't it stream raw binary as an input parameter?
0
Jonathan
8/8/2013 9:28:34 AM
It seems when adding content data to the request body in a POST command, DataSnap server insists that this data is always JSON.  This is why when using TStream as an input parameter, the stream data is converted to a JSON array of integers (bytes) by the Delphi DataSnap client.  This format is very size inefficient as with upto 3 digits per byte, plus the comma, the size of the data being uploaded can grow by as much as 4 times.

What I have therefore done instead is to encode the data to upload in Base64.  My server method now looks like this :
{code}function TServerMethods.updateUploadFile(sFilename: string; Base64Data: TJSONObject): string;{code}
Notice I'm wrapping the Base64 string in a TJSONObject.  This is because if you just specify a String type, the Delphi DataSnap client will call the method with a GET and attempt to put the whole Base64 string in the URL path, causing a 'Connection Closed Gracefully' error.  Using a TJSONObject forces DataSnap to use a POST and put the data in the content body.  The JSON object passed is a single pair object :
{code}{"UploadedData":"JVBERi0xLjMNCiXi48B5SiWGTK3PaY.........."}{code}
This way the size of the data uploaded is much smaller and faster to transfer.  I'd still prefer to be able to stream the raw data in the content body but DataSnap doesn't allow this.
0
Jonathan
8/9/2013 8:19:45 AM
Hello,

thanks for this tip. I have used this methode in my project, too. But if the 
Base64 string is > 40 - 50 KB I will get an "internal server error". Note: I 
have published this as an ISAPI on IIS. Perhaps the limitation is on the IIS 
side?
Any ideas?

Regards
Mathias

> {quote:title=Jonathan Wareham wrote:}{quote}
> It seems when adding content data to the request body in a POST command, DataSnap server insists that this data is always JSON.  This is why when using TStream as an input parameter, the stream data is converted to a JSON array of integers (bytes) by the Delphi DataSnap client.  This format is very size inefficient as with upto 3 digits per byte, plus the comma, the size of the data being uploaded can grow by as much as 4 times.
> 
> What I have therefore done instead is to encode the data to upload in Base64.  My server method now looks like this :
> {code}function TServerMethods.updateUploadFile(sFilename: string; Base64Data: TJSONObject): string;{code}
> Notice I'm wrapping the Base64 string in a TJSONObject.  This is because if you just specify a String type, the Delphi DataSnap client will call the method with a GET and attempt to put the whole Base64 string in the URL path, causing a 'Connection Closed Gracefully' error.  Using a TJSONObject forces DataSnap to use a POST and put the data in the content body.  The JSON object passed is a single pair object :
> {code}{"UploadedData":"JVBERi0xLjMNCiXi48B5SiWGTK3PaY.........."}{code}
> This way the size of the data uploaded is much smaller and faster to transfer.  I'd still prefer to be able to stream the raw data in the content body but DataSnap doesn't allow this.
0
Mathias
10/28/2013 12:50:21 PM
Hello,

thanks for this tip. I have used this methode in my project, too. But if the 
Base64 string is > 40 - 50 KB I will get an "internal server error". Note: I 
have published this as an ISAPI on IIS. Perhaps the limitation is on the IIS 
side?
Any ideas?

Regards
Mathias

<Jonathan Wareham> schrieb im Newsbeitrag 
news:602687@forums.embarcadero.com...
> It seems when adding content data to the request body in a POST command, 
> DataSnap server insists that this data is always JSON.  This is why when 
> using TStream as an input parameter, the stream data is converted to a 
> JSON array of integers (bytes) by the Delphi DataSnap client.  This format 
> is very size inefficient as with upto 3 digits per byte, plus the comma, 
> the size of the data being uploaded can grow by as much as 4 times.
>
> What I have therefore done instead is to encode the data to upload in 
> Base64.  My server method now looks like this :
> {code}function TServerMethods.updateUploadFile(sFilename: string; 
> Base64Data: TJSONObject): string;{code}
> Notice I'm wrapping the Base64 string in a TJSONObject.  This is because 
> if you just specify a String type, the Delphi DataSnap client will call 
> the method with a GET and attempt to put the whole Base64 string in the 
> URL path, causing a 'Connection Closed Gracefully' error.  Using a 
> TJSONObject forces DataSnap to use a POST and put the data in the content 
> body.  The JSON object passed is a single pair object :
> {code}{"UploadedData":"JVBERi0xLjMNCiXi48B5SiWGTK3PaY.........."}{code}
> This way the size of the data uploaded is much smaller and faster to 
> transfer.  I'd still prefer to be able to stream the raw data in the 
> content body but DataSnap doesn't allow this.
0
Mathias
10/28/2013 2:39:32 PM
Hi Mathias,

I've only ever built DataSnap servers as a standalone Windows service EXE, and have not had any problems with the size of upload.  I have however heard of problems with ISAPI DLLs.  Somebody has reported the same problem to Embarcadero here :

http://qc.embarcadero.com/wc/qcmain.aspx?d=118366

I don't know if there's a solution but I guess it's worth looking at IIS settings.

Jonathan
0
Jonathan
10/28/2013 9:42:12 PM
> {quote:title=Jonathan Wareham wrote:}{quote}
> Hi Mathias,
> 
> I've only ever built DataSnap servers as a standalone Windows service EXE, and have not had any problems with the size of upload.  I have however heard of problems with ISAPI DLLs.  Somebody has reported the same problem to Embarcadero here :
> 
> http://qc.embarcadero.com/wc/qcmain.aspx?d=118366
> 
> I don't know if there's a solution but I guess it's worth looking at IIS settings.
> 
> Jonathan

Has anybody solved this problem?
0
Mik
11/25/2013 9:48:58 AM
Looks like this bug has now been fixed in the new XE5 Update 2, see the following links :

http://edn.embarcadero.com/article/43522

http://qc.embarcadero.com/wc/qcmain.aspx?d=116417

Jonathan
0
Jonathan
12/11/2013 8:44:47 AM
Reply:

Similar Artilces:

DataSnap
Hi, I've written a DataSnap server method that returns a TStream object to transfer a file. The client application calls the method and reads the stream to download the file. The server method is very simple : {code} function TServerMethods.DownloadFile(sFilePath: string): TStream; var strFileStream: TFileStream; begin strFileStream := TFileStream.Create(sFilePath, fmOpenRead); Result := strFileStream; end; {code} It works fine downloading many file types (PDF, GIF, BMP, ZIP, EXE) but it doesn't work when downloading JPG files. On the client side the stream objec...

Datasnap Rest client and no datasnap server
Hi, it's possible to use a delphi datasnap rest client to consume a rest web services written in other lenguages (like java or php) or i have to use an idhttp (or other) component? Thanks. Bye Pasquale Di Giovanni wrote: > > it's possible to use a delphi datasnap rest client to consume a rest > web services written in other lenguages (like java or php) or i have > to use an idhttp (or other) component? You could in theory, but it may be more trouble than its worth. You'd probably have to have control of the REST server so you can implement all the...

DataSnap/REST
Hello, I am having problem to trying to send a file or JSON class for the server. The return of the server is "message content is not a valid json value". I use Delphi XE5. Also, I'm using the RESTClient and RESTRequest components for the connection. Below is my routine client and server. {code} {Call} SendExame('C:\Users\xxx\Pictures\Image01.png'); {Client} procedure SendExame(file_path: String); var jsonObj: TJSONObject; mStream: TMemoryStream; aParam: TRESTRequestParameter; begin jsonObj := TJSONObject.Create; try mStream := T...

Datasnap REST server receiving large files
I have a Delphi Rest server running on a windows machine which has methods used by a PHP server. The PHP server can accept a file for upload by a user via their browser. The PHP server then calls a method on the REST server to accept the encoded contents of the file for decoding and storage on the windows machine. These files can be up to 20MB. Sending the contents as a single string crashes the rest server with "Max Line Length Exceeded" (I'm presuming the DSHTTPService has a line-length limit somewhere set to the default 16384 but cannot find it). I am sure that there is als...

DataSnap/REST
Hello, I am having problem to trying send a file or JSON class for the server. The return of the server is "message content is not a valid json value". I use Delphi XE5. Also, I'm using the RESTClient and RESTRequest components for the connection. Below is my routine client and server. {code} {Call} SendExame('C:\Users\xxx\Pictures\Image01.png'); {Client} procedure SendExame(file_path: String); var jsonObj: TJSONObject; mStream: TMemoryStream; aParam: TRESTRequestParameter; begin jsonObj := TJSONObject.Create; try mStream := TMem...

How to upload large file to datasnap server with jquery ? [Edit]
Can someone tell me how to upload/download file (maybe large file like video) to datasnap rest server with jquery? Edited by: w xm on Dec 27, 2010 6:41 AM I don't know that why people never answer to someone question. Even i am also looking to answer of that question but unfortunately nobody posted here. ...

XE3 - DataSnap - server - HTML client
i need to any one to help me to upload and download file throw datasnap server and html - javascript. Hi ahmed, Delphi ships with sample located in: C:\Users\Public\Documents\RAD Studio\11.0\Samples\Delphi\DataSnap\FishFacts\. There you will find example of download image from DataSnap server to HTML - JavaScript client. Best regards, Erwin > {quote:title=Erwin Mouthaan wrote:}{quote} > Hi ahmed, > > Delphi ships with sample located in: C:\Users\Public\Documents\RAD Studio\11.0\Samples\Delphi\DataSnap\FishFacts\. > > There you will find example of downloa...

file uploader save file on server and in database and upload this file on client
hi,i have a file uploader control user can attach files (.rar, .zip, etc) and store file folder and path in database. and another user can click of attach link and can download that file. how can i do this please solve out this problem. you can find your problem solution in this link and you can store the file name in your database server.http://www.aspnettutorials.com/tutorials/network/net-fileupload-aspnet2-csharp.aspxPlease Mark as Answred If This Blog has Helped You.RegardsMitesh Darjihttp://www.indianic.comhttp://www.mitatdotnet.blogspot.com As always there are many ways and which ...

Indy 10
This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. --JivePart=_39eb5.zeB8CwDOH5aMJzMl Content-Type: text/plain; charset="Utf-8" The udp client component would be used in the datasnap server. The udp server component would be used in the datasnap client. --JivePart=_39eb5.zeB8CwDOH5aMJzMl Content-Type: application/x-zip-compressed; name="UDPDSClinetstub.zip" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="UDPDSClinetstub.zip" UEs...

DataSnap REST Server as ISAPI calling a COM Object/Server -> access denied
Hello, I have an DataSnap REST Server published on an IIS webserver as ISAPI. The REST Server calls a COM Server. If I create a normale VCL test client which calls the COM Server it will work. If I call the COM Server from the ISAPI I get the error "access denied". I think it is not a problem of Delphi DataSnap. It should be a problem of IIS user permissions. Did someone know how to setup IIS user permissions to work? Note: If I add the AppPoolUser to the admin group it will work. But it is not a good idea :-) regards M. Pannier ...

Datasnap rest server + CORS
Does the datasnap rest server support [https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS] (Cross-site HTTP requests)? I've created a simple datasnap rest server with basic authentication. The server runs on domain A. The client is a javascript app that will run on a mobile device. The client will always make requests from a different domain. If I test the app in a browser (chrome) or on the mobile the request always gives error 401 (unauthorized). If I look at the debug console, the first request send is an OPTIONS request. This is also described in the CORS pr...

XE Datasnap Client expection with a XE2 DataSnap Server.
I have developed a simple DataSnap Server on XE2 and the client that connects to this server is under XE. Everything works just fine except when freeing the ClientProxy Module on the client side I get the following exception " TDXError with message Invalid Ordinal 3." followed by a AV. Any hints how to avoid this exception or the Server must be on XE also? Thanks in Advance, Omar Zelaya I have now the DataSanp Server on XE and the client no longer throws the exception. So the question now is, it is possible to use a XE DataSnap Client with a XE2 DataSnap Se...

Uploading files to a different file server but not web server
Hi, I want to upload files to a different file server than the web server using asp.net, is that possible?I can use Server.MapPath to store it on the same server. How do I save it to a different machine? What all I need? Do I need IP address? Do I need to have a shared folder on that machine? thank u for the help!!! There is only a few built in ways to get a file from one machine to another in windows.  Things like FTP, HTTP, or File Sharing - you are going to need a path to the server.  You cannot upload directly to that server.  You'll need to upload to your web s...

Upload multiple files to the server without using File Upload
I want to upload multiple files to the server without using input type file (File Upload). Is there a way to do this. What I want to do is retrieve multiple file paths (paths are displayed in a user control like text boxes) and upload those files to the server as a bunch. I tried to set the value of the File Upload cotrol (using javascript) but it was not succeed since attributes of the File Upload are readonly. (document.getElementById("fileUploadValue").value = "C:\Test.txt") Is there a way to override the values in File Upload control or is there a way to up...

Web resources about - Upload file to DataSnap REST server via TStream - embarcadero.datasnap

Companies Directory - Job Fusion
D1 Locker D2L D4D Technologies DAA Deutsche Auftragsagentur Dabble Dabble DB Dabee Dabizmo DabKick Dabo Health Dacentec Dachis Group ...

Embarcadero Webinars
Advanced software tools for application developers and database professionals. Cross-platform solutions for database design, development and ...

David I - Head is in the cloud, feet planted firmly in the ground
... I’s (David Intersimone) Embarcadero blog about programming, languages, databases, history, and more. , and filed under Cloud Computing , DataSnap ...

RAD Studio 2015 Roadmap
Rad Studio, Delphi, C++Builder, and Appmethod 2015 Technology Roadmap from JT at EmbarcaderoTechnologies

FireMonkey Q&A
Questions and answers from a FireMonkey webinar

Contact Us - Ginktage
Home Privacy Policy Contact Us Home .NET Events Microsoft Office SQL Server Tools Gadgets Technology Tips&Tricks Contact Us Ginktage Learn , ...

News Briefs: December 15, 2008 - SD Times: Software Development News
AccuSoft creates an SDK for Web imaging software, while Artisan releases a free version of Artisan Studio. Also, Bredex, Embarcadero, Ilog and ...

Craig Stuntz’s Weblog : Site Map
Craig Stuntz’s Weblog F# • Compilers • Programming Languages • Functional Programming • Web Skip to content Home About Site Map Site Map Share ...

iBeacon Hack Makes It More Efficient To Wait Tables
Here at the 2014 TechCrunch Disrupt SF hackathon two-man hack team, Ray Ho and Mark Watson, showed off a simple but promising concept that combines ...

Te Waka o Delphi · Poll Archives
Keeping Delphi afloat in Aotearoa

Resources last updated: 12/28/2015 12:26:02 AM