2

I'm trying to add a folder to a document library using REST in a SharePoint 2013 SharePoint hosted app. It is hosted in an Office 365 developer site. I'm following the guidelines in MSDN here as well as using the excellent samples on dev.office.com (especially the REST Helper).

While capturing the request during debugging I can't see any problems with my request compared to the documentation and samples. I haven't had issues with any GET requests either.

Here is my request:

var datatext = "{'__metadata': {'type': 'SP.Folder'}, 'ServerRelativeUrl': '" + serverRelativeUrl + foldername + "'}";

$.ajax({
    url : $appweburl + "/_api/web/folders",
    type: "POST",
    data: datatext,
    headers: {
        "accept": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(),
        "content-type": "application/json;odata=verbose",
        "content-length": datatext.length
    },
    success: function (data) {
        success(data);
    },
    error: function (data) {
        failure(data);
    }
});

This generates an error "value does not fall within the expected range"

So this uses "data" instead of "body" because "body" was always generating a JSON Reader error. All of the samples indicate "body" but I found other sources that show this key should be "data" in a POST like this, and it resolves the JSON reader error. I ensure that ServerRelativeUrl leads with a "/" as well as filename.

Any help is greatly appreciated.

EDIT: To follow up on this, I was successful using JSOM only. It turns out that you must add a ListItem to the list and specify the content type to be a folder to achieve this. It works, but it makes me wonder if you have to do something similar in REST - that is rather than use the folder endpoints, do it like adding a listitem to a list. I have not confirmed it.

1 Answers1

2

Usually the error Value does not fall within the expected range occurs since ServerRelativeUrl property was specified in incorrect format.

The following formats are supported:

  • [Document Library]/[New Folder] list/library relative url
  • /[Site]/[Web]/[Document Library]/[New Folder] - site collection relative url
  • http(s)://[Server]/[Site]/[Web]/[Document Library]/[New Folder]
    absolute url

How to create a Folder using SharePoint 2013 REST

Assume the following site structure:

`News` site (under `sites` managed path)
   |
   `Documents` library
       |
      `Archive` folder

Then the following examples demonstrate how to create a folder named 2010 in Documents library:

Example 1

createFolder(_spPageContextInfo.webAbsoluteUrl,'/sites/news/Documents/Archive/2011')
.done(function(data)
{
    var folder = data.d;
    console.log('Folder ' + folder.Name  + ' has been created successfully');
})
.fail(
function(error){
    console.log(JSON.stringify(error));
});

Example 2

createFolder(_spPageContextInfo.webAbsoluteUrl,'Documents/Archive/2010')
.done(function(data)
{
    var folder = data.d;
    console.log('Folder ' + folder.Name  + ' has been created successfully');
})
.fail(
function(error){
    console.log(JSON.stringify(error));
});

where

function executeRequest(url,method,headers,payload) 
{
    if (typeof headers == 'undefined' || headers == null){
        headers = {};
    }
    headers["Accept"] = "application/json;odata=verbose";
    if(method == "POST") {
        headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
    }   

    var ajaxOptions = 
    {       
       url: url,   
       type: method,  
       contentType: "application/json;odata=verbose",
       headers: headers
    };
    if(method == "POST") {
      ajaxOptions.data = JSON.stringify(payload);
    }  

    return $.ajax(ajaxOptions);
}

function createFolder(webUrl,folderUrl) 
{    
    var url = webUrl + "/_api/web/folders";   
    var folderPayload = { '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': folderUrl}; 
    return executeRequest(url,'POST',null,folderPayload);
}
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • Thank you, but I still can't fix this issue. I have a list (document library) called "Deals" and it's properties are: Title: Deals Url: Lists/Deals I want to programmatically add a folder called "test" so the body of my request is: {'__metadata': {'type': 'SP.Folder'}, 'Name': 'test', 'ServerRelativeUrl': '/Deals/test'} and the endpoint is [appweb]/_api/web/folders Doesn't work, so I thought that maybe the RootFolder URI is the the "real" ServerRelativeUrl. That value is [appWeb]/_api/Web/Lists(guid'9bd8dd1f-7036-4afd-9392-48792adee73b')/RootFolder Seemed wrong and it didn't work either... – lachlanpatterson Jan 29 '15 at 04:07
  • After spending several days trying to get a REST POST to work I'm going to have to go back to JSOM. I'm pretty sure the implementation with SharePoint Online is just flawed. I've even been running the samples straight from dev.office.com and they break the same way - GETs work (mostly) and POSTs all fail. Seems REST is not ready for production in SharePoint Online. – lachlanpatterson Jan 30 '15 at 02:21
  • I just realized (after reading the question again) that in your example $appweburl probably points to App web, if so, then it is incorrect. Since the context for /_api/web/folders endpoint really matters please make sure that you specify the proper Host web url (NOT app web url) – Vadim Gremyachev Jan 30 '15 at 13:05
  • By that do you mean that you cannot POST to the appweb? If this is the case then only cross-domain POST requests are allow. That would seem very odd to me, and not match the examples I've seen. However I will try the cross-domain approach with @target and see if it works... – lachlanpatterson Feb 01 '15 at 02:55
  • Trying to post with the endpoint starting at the hostweb simply gives me a permission error. However I've successfully managed to create a list, list item, and even subweb by REST using other samples! I still can't find a real working example to create a folder though. The documented endpoint just doesn't work or the documentation is incomplete. – lachlanpatterson Feb 02 '15 at 01:22