7

After a lot of research I finally got uploads via REST working in SharePoint 2013. But I would like to provide additional properties to the Add Function like Title. This code works so far but the only thing I can do is setting the filename.

var targetRESTUrl = _spPageContextInfo.webServerRelativeUrl +
       "/_api/web/GetFolderByServerRelativeUrl('" + serverRelativeUrl + "')/Files" +
       "/Add(url='" + newfilename + "', overwrite=true)";

$.ajax({
   url: targetRESTUrl,
   type: "POST",
   data: arrayBuffer,

... etc. ...

The MSDN is very unhelpful there, saying only that Add has Parameters...

I think I saw somewhere additional Parameters or whatever they were but I cannot find that site any more. It looked like this

var targetRESTUrl = webRelativeUrl +
       "/_api/web/GetFolderByServerRelativeUrl('" + relativeUrl + "')/Files" +
       "/Add(url='" + newfilename + "', overwrite=true)@TargetFileName=something";

I am talking about that @key=value at the end. Is this some Standard REST functionality or SP specific? Is there some more Information about this somewhere on the net?

How can I add additional informations to this request? Or do I have to update the file after the upload succeeded? (If I have to update it afterwards, how do I do this?)

  • Hi @Kirschi , could you please provide the full working code for uploads with only title? I tried lots of thing, but it just doesn't work... :/ – Gintas K Apr 13 '16 at 9:17
8

You have to make three calls. The first uploads the file, the second retrieves the list item associated with the file that was just uploaded, and the third sets the field values

function uploadDocument() {
    if (!window.FileReader) {
        alert("This browser does not support the HTML5 File APIs");
        return;
    }

    var element = document.getElementById("uploadInput");
    var file = element.files[0];
    var parts = element.value.split("\\");
    var fileName = parts[parts.length - 1];

    var reader = new FileReader();
    reader.onload = function (e) {
        addItem(e.target.result, fileName);
    }
    reader.onerror = function (e) {
        alert(e.target.error);
    }
    reader.readAsArrayBuffer(file);

    function addItem(buffer, fileName) {
        var call = uploadDocument(buffer, fileName);
        call.done(function (data, textStatus, jqXHR) {
            var call2 = getItem(data.d);
            call2.done(function (data, textStatus, jqXHR) {
                var item = data.d;
                var call3 = updateItemFields(item);
                call3.done(function (data, textStatus, jqXHR) {
                    var div = jQuery("#message");
                    div.text("Item added");
                });
                call3.fail(function (jqXHR, textStatus, errorThrown) {
                    failHandler(jqXHR, textStatus, errorThrown);
                });
            });
            call2.fail(function (jqXHR, textStatus, errorThrown) {
                failHandler(jqXHR, textStatus, errorThrown);
            });
        });
        call.fail(function (jqXHR, textStatus, errorThrown) {
            failHandler(jqXHR, textStatus, errorThrown);
        });
    }

    function uploadDocument(buffer, fileName) {
        var url = String.format(
            "{0}/_api/Web/Lists/getByTitle('Project Documents')/RootFolder/Files/Add(url='{1}', overwrite=true)",
            _spPageContextInfo.webAbsoluteUrl, fileName);
        var call = jQuery.ajax({
            url: url,
            type: "POST",
            data: buffer,
            processData: false,
            headers: {
                Accept: "application/json;odata=verbose",
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "Content-Length": buffer.byteLength
            }
        });

        return call;
    }

    function getItem(file) {
        var call = jQuery.ajax({
            url: file.ListItemAllFields.__deferred.uri,
            type: "GET",
            dataType: "json",
            headers: {
                Accept: "application/json;odata=verbose"
            }
        });

        return call;
    }

    function updateItemFields(item) {
        var now = new Date();
        var call = jQuery.ajax({
            url: _spPageContextInfo.webAbsoluteUrl +
                "/_api/Web/Lists/getByTitle('Project Documents')/Items(" +
                item.Id + ")",
            type: "POST",
            data: JSON.stringify({
                "__metadata": { type: "SP.Data.Project_x0020_DocumentsItem" },
                Year: now.getFullYear()
            }),
            headers: {
                Accept: "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "IF-MATCH": item.__metadata.etag,
                "X-Http-Method": "MERGE"
            }
        });

        return call;
    }

    function failHandler(jqXHR, textStatus, errorThrown) {
        var response = JSON.parse(jqXHR.responseText);
        var message = response ? response.error.message.value : textStatus;
        alert("Call failed. Error: " + message);
    }
}
  • Thank you for also providing the code needed. Ok three calls, well makes sense. So the updated properties are specified in data: "__metadata":. How do I find out what they are called? Are they named the same as in C#? Or are those properties specified in your example the List columns? Because Year irritates me. – Kirschi Aug 19 '13 at 11:26
  • 1
    In my example, Year is a field in the Project Documents library and I`m setting its value to the current year. So yes, the pattern you use is the same as in C#. The internal name of the field goes on the left side of the colon and the new value for that field goes on the right side of the colon. – Rob Windsor Aug 19 '13 at 12:45
  • When the file is initially uploaded, is it automatically assigned the default content type of the library? And can the content type be changed while setting the field values? – athom Mar 13 '14 at 20:37
  • Could not make it working. I got can not set header error for Content-Length. I have the plural sight subscription but can not run your solution. Error I get Error 1 Could not write lines to file "obj\Debug\\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs". The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. JavaScriptRestDemos – Atish Dipongkor Oct 9 '15 at 16:28
  • I regularly have similar errors. You need to move your solution to a path with a shorter name. For example, if the folder name is "C:\Users\Rob Windsor\Documents\Visual Studio 2013\Projects\SharePointApp1", try shortening it to "C:\Users\Rob Windsor\Documents\Visual Studio 2013\Projects\Rest" or even "C:\Users\Rob Windsor\Documents\Projects\Rest". That should fix the issue. – Rob Windsor Oct 9 '15 at 20:13

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.