Hello
I need to write a web service that will cater for the uploading of a file. It is all a bit new to me and I need some help with and error I am getting. I have been using the examples in the documentation to create some test examples.
Here is the web service module, pretty much cribbed from the documentation example:
import com
import fgl gws_pri
main
define ret integer
call com.WebServiceEngine.RegisterRestService("gws_pri", "pri")
display "Server started"
call com.WebServiceEngine.Start()
while true
let ret = com.WebServiceEngine.ProcessServices(-1)
case ret
when 0
display "Request processed."
when -1
display "Timeout reached."
when -2
display "Disconnected from application server."
exit program
when -3
display "Client Connection lost."
when -4
display "Server interrupted with Ctrl-C."
when -9
display "Unsupported operation."
when -10
display "Internal server error."
when -23
display "Deserialization error."
when -35
display "No such REST operation found."
when -36
display "Missing REST parameter."
otherwise
display "Unexpected server error " || ret || "."
exit while
end case
if int_flag <> 0 then
let int_flag = 0
exit while
end if
end while
display "Server stopped"
end main
Here is the web service function:
import os
import com
public define myerror record attribute(WSError="My error")
code integer,
reason string
end record
public function UploadImage(theimage string attribute(WSMedia="image/*"),
submit string)
attributes (WSPost,
WSPath="/upload",
WSDescription="Upload image file to the server",
WSThrows="400:@myerror")
returns string attribute(WSMedia="text/html")
define sReturn string
define bOK integer
let bOK = os.Path.DELETE("myimage.png")
let bOK = os.Path.RENAME(theimage,"myimage.png")
let sReturn = "<HTML><body><h1>Got image</h1></body></HTML>"
return sReturn
end function
and here is the associated html:
<!DOCTYPE html>
<html>
<FORM NAME="upload" method="post" action="http://localhost:8090/pri/upload" enctype='multipart/form-data'>
<div>
<label>Image File: </label>
<input type="file" name="myimage" accept="image/png" />
</div>
<br>
<input type="submit" name="submit" value="Send"/>
</FORM>
</html>
Here is a snippet of the output, with the full text in the attached file:
Server started
WS-DEBUG (Receive)
POST /pri/upload HTTP/1.1
WS-DEBUG END
WS-DEBUG (Receive)
Host: localhost:8090
Connection: keep-alive
Content-Length: 5520
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3oLWn5iowKFYOJAP
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: cross-site
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
WS-DEBUG END
WS-DEBUG (Receive)
------WebKitFormBoundary3oLWn5iowKFYOJAP\r\nContent-Disposition: form-data; name="myimage"; filename="assess.png"\r\nContent-Type: image/png
.
.
.
WS-DEBUG END
WS-DEBUG (Send)
HTTP/1.1 400 Unable to deserialize field
WS-DEBUG END
Whereas, if I make this web service available, it works:
public function add2(a integer,
b integer,
submit string)
attributes (WSPost,
WSPath="/add2",
WSDescription="Adds A and B",
WSThrows="400:@myerror")
returns string attribute(WSMedia="text/html")
define sReturn string
define iAnswer integer
let iAnswer = a + b
let sReturn = sfmt("<HTML><body>Got answer %1</body></HTML>", iAnswer)
return sReturn
end function
Can anyone see why the former is not working?
Are you missing a WSAttachment?
Hi Reuben
Yes, perhaps. I see that the documentation has been updated and the example given for uploading an image in multipart has changed and does now include the WSAttachment attribute - my fault for not checking the very latest documentation.
However, I am now getting a BadHTTPRequest error (-5 being returned from com.WebServiceEngine.ProcessServices). This is using the exact code within the documentation on my local machine.
Gary
Hi
Just by way of an update - the examples that are contained in the latest version of the documentation that demonstrate a restful web service to upload a file to a server do indeed work.
Using that as the basis I have now managed to achieve my goal of creating a web component I can add to forms to provide a "drag and drop" area for uploading files to our archive management, so I and the users are very pleased!
Gary
Quote from: Gary C. on November 13, 2019, 09:07:08 AM
Hi
Just by way of an update - the examples that are contained in the latest version of the documentation that demonstrate a restful web service to upload a file to a server do indeed work.
Using that as the basis I have now managed to achieve my goal of creating a web component I can add to forms to provide a "drag and drop" area for uploading files to our archive management, so I and the users are very pleased!
Gary
feel free to share more details here of your solution or perhaps on GitHub. Or work with your support contact to pull out the important bits to create a simple example. I know some customers are impacted when moving from desktop to web, and the inability to drop files onto a display array and don't really like the model of an openfile front-call being required before the FGL_GETFILE.
Reuben
PS Make sure you test what happens if your users just miss the drop area when attempting to drop in your web component...