Handling File Attachments in SharePoint Hosted apps using REST API

Posted on Updated on

SharePoint List items can have one or more attachments. This post describes how to save/upload attachments and how to retrieve/download them for a specific list item in a list using SharePoint client REST API using Javascript.

Uploading an Attachment to SharePoint List using REST API using Javascript

First we have to read the file content and then upload the file to the list item as an attachment. I have used HTML 5 FileReader in order to read the file content. You have to pass the control id of your file input control to the following function. The function returns a promise that we can use to get the output.

   1: function readFile (uploadControlId) {

   2:  

   3:      if (!window.FileReader)

   4:          throw "The browser does not support HTML 5";

   5:  

   6:      var def = new $.Deferred();

   7:  

   8:      var element = document.getElementById(uploadControlId);

   9:      var file = element.files[0];

  10:      var parts = element.value.split("\\");

  11:      var fileName = parts[parts.length - 1];

  12:  

  13:      var reader = new FileReader();

  14:      reader.onload = function (e) {

  15:          def.resolve(e.target.result, fileName);

  16:      }

  17:      reader.onerror = function (e) {

  18:          def.reject(e.target.error);

  19:      }

  20:  

  21:      reader.readAsArrayBuffer(file);

  22:  

  23:      return def.promise();

  24:  }

 

The following function upload the attachment to the specified list. It takes the ID of the list item as the first parameter, list name as the second parameter, file name and buffer go as third and fourth parameters which we get from the above function.

   1: function uploadAttachment (id, listName, fileName, buffer) {

   2:         var url = _spPageContextInfo.webServerRelativeUrl +

   3:             "/_api/web/lists/getByTitle('" + listName + "')/items('" + id.toString() + "')/AttachmentFiles/add(FileName='" + fileName + "')";

   4:  

   5:         return $.ajax({

   6:             url: url,

   7:             type: "POST",

   8:             data: buffer,

   9:             processData: false,

  10:             headers: {

  11:                 Accept: "application/json;odata=verbose",

  12:                 "X-RequestDigest": $("#__REQUESTDIGEST").val(),

  13:                 "Content-Length": buffer.byteLength,

  14:                 "IF-MATCH": "*"

  15:             }

  16:         });

  17:     },

Now we have the function to read the file content and the other function to upload the content as an attachment to a list item, so next we have to chain them together to make a proper call. We do the chaining using the .done function.

   1: function executeUploadAttachment (id, listname) {

   2:         readFile("uploadControlId").done(function (buffer, fileName) {

   3:             uploadAttachment(id, listname, fileName, buffer).done(function () {

   4:                 alert("success");

   5:             }).fail(function () {

   6:                 alert("error in uploading attachment");

   7:             })

   8:         }).fail(function (err) {

   9:             alert("error in reading file content");

  10:         });

  11: }

 

Downloading the attachments of a list item

This is pretty straight forward.  The following URL will give the relative URLs of the attachments of a list item.

_spPageContextInfo.webServerRelativeUrl + /_api/web/lists/getbytitle(‘” + listname + “’)/items(‘” + id.toString() + “’)/AttachmentFiles

   1: function getAttachments (id, listname) {

   2:         return $.ajax({

   3:             url: _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/getbytitle('" + listname + "')/items('" + id.toString() + "')/AttachmentFiles",

   4:             type: "GET",

   5:             contentType: "application/json;odata=verbose",

   6:             headers: {

   7:                 "Accept": "application/json;odata=verbose"

   8:             }

   9:         });

  10:     }

Use the following code snippet get the output.

   1: getBillingAttachments(1, "mylist").done(function (data) {

   2:                 var result = data.d.results;

   3:  

   4:                 for (var i = 0; i < result.length; i++) {

   5:                     alert(result[i].ServerRelativeUrl);

   6:                }

   7:             })

Advertisements

6 thoughts on “Handling File Attachments in SharePoint Hosted apps using REST API

    sarang said:
    September 3, 2014 at 8:32 PM

    what is buffer

      thuruinhttp said:
      September 4, 2014 at 12:48 PM

      buffer is the parameter (which is a byte Array) which holds the file contents.

    Joseph said:
    September 25, 2014 at 2:57 PM

    Do you know maybe how to update attachment ? Because at the moment I am only available to upload file. I have already found some solution but none of them worked (e.g. GetFolderByServerRelativeUrl or GetFileByServerRelativeUrl). I have alsod tried to add “add(FileName='” + fileName + “‘,overwrite=true)”;” did not work.
    Best regards

    Mark Altman said:
    March 17, 2016 at 9:09 PM

    Thanks for a great post. The issue I have is that my form has 4 attachment fields. I’m able to add and retrieve attachments now, but I’m not able to distinguish which list field the attachments should be associated with.

    markaltman1 said:
    March 17, 2016 at 9:11 PM

    Thanks Thuru, this all works well. However, my issue is that my list has 4 attachments fields. I have been unable to associate upload or download attachments with specific fields.

      Thuru responded:
      March 22, 2016 at 10:13 PM

      Hi markaltman1, it’s been while that I touched SharePoint, I understand your question but do not have a quickly available environment to test and give you a solution. Please feel free to post your question here http://melick-rajee.blogspot.com/.

      He’s a SharePoint MVP and definitely help you.

Comments are closed.