Add Attachment to the List Item Using REST API in SharePoint

19 comments
Hi All,

In a following post we will see  how to add attachment to the List Item by using REST API in SharePoint 2013.In One my post we have already seen Add List items using REST API.
We need to add JQuery reference to our script.In a following post I am adding reference from http://code.jquery.com/jquery-1.10.2.js

Please find the below Code Snippet, which was used in SharePoint Hosted Apps, You need to change the code (Url like HostUrl and AppUrl ) if you want to use the same code in regular development.

'use strict';
var SPAppWebUrl;
var SPHostUrl;

(function () {
    // This code runs when the DOM is ready and creates a context object which is
    // needed to use the SharePoint object model
    $(document).ready(function () {
        SPHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
        SPAppWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
        ItemSubmit();
    });

    function getQueryStringParameter(urlParameterKey) {
        var params = document.URL.split('?')[1].split('&');
        var strParams = '';
        for (var i = 0; i < params.length; i = i + 1) {
            var singleParam = params[i].split('=');
            if (singleParam[0] == urlParameterKey)
                return decodeURIComponent(singleParam[1]);
        }
    }
    function ItemSubmit() {
        //Button click Event to upload files to List Item
        $("#btnSubmit").click(function () {
            //checking Whether document is uploaded or not - Validation
            if (document.getElementById("inputFile").files.length === 0) {
                alert("Select a file..and click on submit");
                return;
            }
            else {
                //Reading the Uploadef file values
                var parts = document.getElementById("inputFile").value.split("\\");
                var filename = parts[parts.length - 1];
                var file = document.getElementById("inputFile").files[0];
                //TestList - is our Listname
                //1 - is our List Item ID
                //filename - File Name of the attachment
                //file - file data
                uploadFileSP("TestList", "1", filename, file);
            }
        });
    }
    function getFileBuffer(file) {
        var deferred = $.Deferred();
        var reader = new FileReader();
        reader.onload = function (e) {
            deferred.resolve(e.target.result);
        }
        reader.onerror = function (e) {
            deferred.reject(e.target.error);
        }
        reader.readAsArrayBuffer(file);
        return deferred.promise();
    }

    //Used to Add Attachemnt to List Item
    function uploadFileSP(listName, id, fileName, file) {
        var deferred = $.Deferred();
        getFileBuffer(file).then(
              function (buffer) {
                  var bytes = new Uint8Array(buffer);
                  var content = new SP.Base64EncodedByteArray();
                  var queryUrl = SPAppWebUrl + "/_api/SP.AppContextSite(@target)" + "/web/lists/getbytitle('" + listName + "')/items(" + id +
    ")/AttachmentFiles/add(FileName='" + file.name + "')?" + "@target='" + SPHostUrl + "'";
                  $.ajax({
                      url: queryUrl,
                      type: "POST",
                      processData: false,
                      contentType: "application/json;odata=verbose",
                      data: buffer,
                      headers: {
                          "accept": "application/json;odata=verbose",
                          "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                          "content-length": buffer.byteLength
                      }, success: onAttachmentSucess,
                      error: onAttachmentFailure
                  });
              },
                function (err) {
                    deferred.reject(err);
                });
        return deferred.promise();
    }
    function onAttachmentSucess() {
        alert("Successfully Saved Attachment");
    }
    function onAttachmentFailure(error) {
        alert("Attachment Failure:" + error.status + "," + error.statusText);
    }
})();

In Default.aspx
<div>
    <p id="message">
        <!-- The following content will be replaced with the user name when you run the app - see App.js -->
        <input type="file" id="File1" />
        <input type="button" id="Button1" value="Submit">
    </p>
</div>

Regular Way:


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script type="text/javascript">
        var context;
        var web;
        var Url;
        var listItemEntity;
        $(document).ready(function () {
            SP.SOD.executeFunc('sp.js', 'SP.ClientContext', FunctionReady);
            ItemSubmit();
        });
        function FunctionReady() {
            context = new SP.ClientContext.get_current();
            web = context.get_web();
            context.load(web);
            context.executeQueryAsync(onRequestSuccess, onRequestFailure);
        }
        function onRequestSuccess() {
            Url = web.get_url();
            GetListItemEntity(Url);
        }
        function onRequestFailure(sender, args) {
            alert("Error Occured:" + args.get_message());
        }
        //Used to get the List Item Entity Type
        function GetListItemEntity(webUrl) {
            var queryUrl = webUrl + "/_api/lists/getbytitle('TestList')?$select=ListItemEntityTypeFullName";
            $.ajax({
                url: queryUrl,
                method: "GET",
                headers: { "Accept": "application/json;odata=verbose" },
                success: onEntitySuccess,
                error: onEntityFailure
            });
        }
        function onEntitySuccess(data) {
            listItemEntity = data.d.ListItemEntityTypeFullName;
        }
        function onEntityFailure(err) {
            alert(err.statusText);
        }
        function ItemSubmit() {
            //Button click Event to upload files to List Item
            $("#btnSubmit").click(function () {
                //checking Whether document is uploaded or not - Validation
                if (document.getElementById("inputFile").files.length === 0) {
                    alert("Select a file..and click on submit");
                    return;
                }
                else {
                    //Reading the Uploadef file values
                    var parts = document.getElementById("inputFile").value.split("\\");
                    var filename = parts[parts.length - 1];
                    var file = document.getElementById("inputFile").files[0];
                    //TestList - is our Listname
                    //1 - is our List Item ID
                    //filename - File Name of the attachment
                    //file - file data
                    uploadFileSP("TestList", "1", filename, file);
                }
            });
        }
        function getFileBuffer(file) {
            var deferred = $.Deferred();
            var reader = new FileReader();
            reader.onload = function (e) {
                deferred.resolve(e.target.result);
            }
            reader.onerror = function (e) {
                deferred.reject(e.target.error);
            }
            reader.readAsArrayBuffer(file);
            return deferred.promise();
        }      
        function uploadFileSP(listName, id, fileName, file) {
            var deferred = $.Deferred();
            getFileBuffer(file).then(
              function (buffer) {
                  var bytes = new Uint8Array(buffer);
                  var content = new SP.Base64EncodedByteArray();
                  var queryUrl = Url + "/_api/lists/GetByTitle('" + listName + "')/items(" + id + ")/AttachmentFiles/add(FileName='" + file.name + "')";
                  $.ajax({
                      url: queryUrl,
                      type: "POST",
                      processData: false,
                      contentType: "application/json;odata=verbose",
                      data: buffer,
                      headers: {
                          "accept": "application/json;odata=verbose",
                          "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                          "content-length": buffer.byteLength
                      }, success: onAttachmentSucess,
                      error: onAttachmentFailure
                  });
              },
                function (err) {
                    deferred.reject(err);
                });
            return deferred.promise();
        }

        function onQuerySucess() {
            alert('Attachement Added Successfully');
        }

        function onQueryFailure(error) {
            alert("Failure:" + error.status + "," + error.statusText);
        }
    </script>
</head>

<body>
    <input type="file" id="inputFile" />
    <input type="button" id="btnSubmit" value="Submit">
</body>
</html>

As part of demo, I have added the above script in Content Editor.Our Page will contain one File Upload Control and Submit button.
On clicking on submit button we will adding attachment to the existing list Item.
After Adding Script to Content Editor , It will look as follows,

final , output will be look as follows as a success message.

You can download the file from the below link,

https://sites.google.com/site/sharepointkitchenblog/Attachment.html

Thanks.

Related Post

19 comments:

  1. I get attachment failure: 404 not found.

    ReplyDelete
  2. After downloading the attachment html in your download link, it works as expected. I had tried earlier by copying and pasting above code, but that had SPHost and SpAppweb url which was not there in the attachment. Thanks a lot , saved my a$$

    ReplyDelete
  3. I uploaded a textfile as attachment, the content is getting replaced with {metadata:{type:sp.data.listitem}} , so there is still some issue here.

    ReplyDelete
    Replies
    1. I will check again and update on the same... thanks

      Delete
    2. HI,
      I have update the code for Hosted Apps and Regular REST API Dev...
      Thanks...

      Delete
  4. Great post! Do you know if this will work in SP2010? ... or just in SP2013? Thanks!

    ReplyDelete
    Replies
    1. Thanks @David... It will work only in SP2013...

      Delete
    2. I'm trying this now for sp2010... from my assumptions it may work if you change the rest api svc url (/api) -> (listdata.svc)

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Is anyone else looking at the verbosity of this code as a way to sell to management why they need a grown up\big boy backend system versus sharepoint? I feel like when I'm using express life is better and my wife yells at me less while I'm hand parsing URL's and putting break points in that SP library.

    ReplyDelete
  7. function uploadFileSP(listName, id, fileName, file) {..}
    you don't use fileName in this function...

    ReplyDelete
    Replies
    1. nor does he use the bytes or content variables that are declared.

      Delete
  8. Thanks Kaarthikeya,
    The example worked completely fine for me..
    Just one correction : Please update the id of the button and file tag in your HTML to be same as in your js code.

    ReplyDelete
  9. Is it possible to creating and attaching an item to list using Rest API at same time?

    ReplyDelete
  10. AWESOME code, only had to correct a few things but overall, you saved me lots of time/energy - thank you

    ReplyDelete
    Replies
    1. which things, can you share with us

      Delete
  11. how do we stream attachments in a list item using REST api? (how do we get attachment data using REST api)

    ReplyDelete
  12. Very nice post. I just stumbled upon your weblog and wanted to say that I've truly enjoyed surfing around your blog posts. In any case I'll be subscribing to your rss feed and I hope you write again soon!

    ReplyDelete