0

I am new to the SharePoint API. I am trying to create folders in a customer SharePoint solution.

Problem is i'm getting a 403 return. My request.:

POST https://companyname.sharepoint.com/sites/Test/_api/Web/GetFolderByServerRelativePath(decodedurl='/sites/Test/Syra_Test') HTTP/1.1
X-FORMS_BASED_AUTH_ACCEPTED: f
X-RequestDigest:xxxxxxx,28 Apr 2021 10:03:46 -0000
X-HTTP-Method: POST
Cookie: SPOIDCRL=xxxxxxxx
Authorization: 
Host: companyname.sharepoint.com
Content-Length: 69
Expect: 100-continue

{'__metadata': {'type':'SP.Folder'},'ServerRelativeUrl': '/syraHest'}

My response.:

<?xml version="1.0" encoding="utf-8"?><m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code>-2130575251, System.Runtime.InteropServices.COMException</m:code><m:message xml:lang="en-US">The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.</m:message></m:error>

Here is my code.:

WebClient client = new WebClient();

            string USER = "xxxxxxxx@xxxxxxxxx.com";
            SecureString passWord = new SecureString();
            string PWD = "xxxxxxxx";
            PWD.ToList().ForEach(passWord.AppendChar);
            SharePointOnlineCredentials credentials = new SharePointOnlineCredentials(USER, passWord);
            client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
            client.Credentials = credentials;
            client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
            client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
            client.BaseAddress = "https://companyname.sharepoint.com/sites/Test";
            // Get Digest
            string digestUrl = "/_api/contextinfo";
            string digestResult = client.UploadString(digestUrl, "POST");
            JToken dr = JToken.Parse(digestResult);
            string digest = dr["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();

            // So far so good! FormDigest is returned here so I know I have correct credentials
            // Add Digest to next request
            client.BaseAddress = "https://companyname.sharepoint.com";
            client.Headers.Add("X-RequestDigest", digest);
            client.Headers.Add("X-HTTP-Method", "POST");                                          
            string endpointUri = "/sites/Test/_api/Web/GetFolderByServerRelativePath(decodedurl='/sites/Test/Syra_Test')/Folders"; 
            string payloadString = "{'__metadata': {'type':'SP.Folder'},'ServerRelativeUrl': '/syraHest'}";                         
            // Fails here 403!!
            string result = client.UploadString(endpointUri, "POST", payloadString);         
            //string result = client.DownloadString(endpointUri);
            JToken t = JToken.Parse(result);
            Console.WriteLine(t);

GET folders and the like works fine, so what am i missing in my POST requests ?

Edited code same result unfortunately.:

SharePointOnlineCredentials credentials = new SharePointOnlineCredentials(USER, passWord);
            client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
            client.Credentials = credentials;
            client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
            client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
            client.BaseAddress = "https://companyname.sharepoint.com";
            // Get Digest
            string digestUrl = "/_api/contextinfo";
            string digestResult = client.UploadString(digestUrl, "POST");
            JToken dr = JToken.Parse(digestResult);
            string digest = dr["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
            // So far so good! FormDigest is returned here so I know I have correct credentials
            // Add Digest to next request            
            client.Headers.Add("X-RequestDigest", digest);
            client.Headers.Add("X-HTTP-Method", "POST");
            string endpointUri = "/sites/Test/_api/Web/folders";
            string payloadString = "{'__metadata': {'type':'SP.Folder'},'ServerRelativeUrl': '/sites/Test/Syra_Test/syraHest'}";
            // Fails here!!
            string result = client.UploadString(endpointUri, "POST", payloadString);           
            JToken t = JToken.Parse(result);
            Console.WriteLine(t);

Edit.: same error but new message.: 403 Access denied. You do not have permission to perform this action or access this resource

request.:

POST https://companyname.sharepoint.com/sites/Test/_api/Web/folders HTTP/1.1
X-RequestDigest: xxxxxxxx,29 Apr 2021 12:16:23 -0000
Accept: application/json;odata=verbose
Content-Type: application/json;odata=verbose
Host: companyname.sharepoint.com
Content-Length: 90
Expect: 100-continue
Connection: Keep-Alive

{'__metadata': {'type':'SP.Folder'},'ServerRelativeUrl': '/sites/Test/Syra_Test/syraHest'}
0

You can find the documentation on working with folders using the REST API here: https://docs.microsoft.com/en-us/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest

According to the documentation the POST to create a folder is:

POST https://{site_url}/_api/web/folders
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"

{
  "__metadata": {
    "type": "SP.Folder"
  },
  "ServerRelativeUrl": "/document library relative url/folder name"
}

With that in mind changing your code to the following should solve your issue:

client.BaseAddress = "https://companyname.sharepoint.com";
client.Headers.Add("X-RequestDigest", digest);
client.Headers.Add("X-HTTP-Method", "POST");     
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");                                     
string endpointUri = "/sites/Test/_api/Web/folders"; 
string payloadString = "{'__metadata': {'type':'SP.Folder'},'ServerRelativeUrl': '/sites/Test/Syra_Test/syraHest'}";                         
string result = client.UploadString(endpointUri, "POST", payloadString);                                
JToken t = JToken.Parse(result);
Console.WriteLine(t);

The last time I checked, this code only creates the folder. It does not create the list item that is associated with the folder. I discuss alternative code you can use to create both the folder and the associated list item in this blog post: SharePoint REST API and Lists with Folders.

5
  • Tried, getting the same 403 forbidden, could it be the digest ? added the reviewed code to the question. – JNA Apr 29 at 5:48
  • I tried this and the Accept and Content-Type headers were not being added to the POST that creates the folder. I updated the code to ensure they were added and everything worked fine. I updated the code sample above accordingly. – Rob Windsor Apr 29 at 11:33
  • Altered the client, i guess i'm a step further but now i still get 403 BUT different message.: 'Access denied. You do not have permission to perform this action or access this resource' . It a library im trying to create folders in, does that need some sort of permissions ? added request to question. – JNA Apr 29 at 12:28
  • The user account you identify with the SharePointOnlineCredentials needs permission to create a folder in the list or library. Also, make sure that /sites/Test/Syra_Test is the correct server-relative URL to the list or library. – Rob Windsor Apr 29 at 13:21
  • The AD user i have has admin rights, isn't that enough ? i can GET files and folders just fine from the relative path. – JNA May 3 at 5:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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