Four Js Development Tools Forum

Discussions by product => GWS => Topic started by: Gary Collis on November 02, 2019, 10:13:35 AM

Title: Unable to Deserialize Field Error
Post by: Gary Collis on November 02, 2019, 10:13:35 AM
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:
Code (genero) Select

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:

Code (genero) Select

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:

Code (html4strict) Select

<!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:

Code (#) Select

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:

Code (Genero) Select

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?


Title: Re: Unable to Deserialize Field Error
Post by: Reuben Barclay on November 06, 2019, 09:44:10 PM
Are you missing a WSAttachment?


Title: Re: Unable to Deserialize Field Error
Post by: Gary Collis on November 07, 2019, 02:48:17 PM
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
Title: Re: Unable to Deserialize Field Error
Post by: Gary Collis 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
Title: Re: Unable to Deserialize Field Error
Post by: Reuben Barclay on November 13, 2019, 08:31:57 PM
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...