How can I send a File over a REST API?

52,303

Solution 1

I'd recommend you look into RestSharp
http://restsharp.org/

The RestSharp library has methods for posting files to a REST service. (RestRequst.AddFile()). I believe on the server-side this will translate into an encoded string into the body, with the content-type in the header specifying the file type.

I've also seen it done by converting a stream to a base-64 string, and transferring that as one of the properties of the serialized json/xml object. Especially if you can set size limits and want to include file meta-data in the request as part of the same object, this works really well.

It really depends how large your files are though. If they are very large, you need to consider streaming, of which the nuances of that is covered in this SO post pretty thoroughly: How do streaming resources fit within the RESTful paradigm?

Solution 2

You could send it as a POST request to the server, passing file as a FormParam.

    @POST
        @Path("/upload")
       //@Consumes(MediaType.MULTIPART_FORM_DATA)
        @Consumes("application/x-www-form-urlencoded")
        public Response uploadFile( @FormParam("uploadFile") String script,  @HeaderParam("X-Auth-Token") String STtoken, @Context HttpHeaders hh) {

            // local variables
            String uploadFilePath = null;
            InputStream fileInputStream = new ByteArrayInputStream(script.getBytes(StandardCharsets.UTF_8));

            //System.out.println(script); //debugging

            try {
                  uploadFilePath = writeToFileServer(fileInputStream, SCRIPT_FILENAME);
            }
            catch(IOException ioe){
               ioe.printStackTrace();
            }
            return Response.ok("File successfully uploaded at " + uploadFilePath + "\n").build();
        }

 private String writeToFileServer(InputStream inputStream, String fileName) throws IOException {

        OutputStream outputStream = null;
        String qualifiedUploadFilePath = SIMULATION_RESULTS_PATH + fileName;

        try {
            outputStream = new FileOutputStream(new File(qualifiedUploadFilePath));
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            outputStream.flush();
        }
        catch (IOException ioe) {
            ioe.printStackTrace();
        }
        finally{
            //release resource, if any
            outputStream.close();
        }
        return qualifiedUploadFilePath;
    }

Solution 3

Building on to @MutantNinjaCodeMonkey's suggestion of RestSharp. My use case was posting webform data from jquery's $.ajax method into a web api controller. The restful API service required the uploaded file to be added to the request Body. The default restsharp method of AddFile mentioned above caused an error of The request was aborted: The request was canceled. The following initialization worked:

// Stream comes from web api's HttpPostedFile.InputStream 
     (HttpContext.Current.Request.Files["fileUploadNameFromAjaxData"].InputStream)
using (var ms = new MemoryStream())
{
    fileUploadStream.CopyTo(ms);
    photoBytes = ms.ToArray();
}

var request = new RestRequest(Method.PUT)
{
    AlwaysMultipartFormData = true,
    Files = { FileParameter.Create("file", photoBytes, "file") }
};
Share:
52,303
Kevin
Author by

Kevin

I'm a Senior .Net Software Engineer

Updated on August 17, 2022

Comments

  • Kevin
    Kevin over 1 year

    I am trying to send a file to a server over a REST API. The file could potentially be of any type, though it can be limited in size and type to things that can be sent as email attachments.

    I think my approach will be to send the file as a binary stream, and then save that back into a file when it arrives at the server. Is there a built in way to do this in .Net or will I need to manually turn the file contents into a data stream and send that?

    For clarity, I have control over both the client and server code, so I am not restricted to any particular approach.

  • Kevin
    Kevin over 8 years
    I don't know what you mean by number 4. What do you mean by "use ready library"? I will look into that other question, I didn't see that when I was searching for an answer earlier.
  • Kevin
    Kevin over 8 years
    This is precisely what I needed, thanks for the push in the right direction.
  • Daniel Golub
    Daniel Golub over 8 years
    There are a couple of ready out-of-the-box libraries for file uploading in .NET A couple of them are: msdn.microsoft.com/en-us/library/… nuget.org/packages/AjaxUploader