MaPi
MaPi

Reputation: 1601

Create folder structure in a Sharepoint online list

I'm trying to create a folder structure under a list in Sharepoint online. I created a list called Shared1 according to this article:

http://blogs.technet.com/b/catastrophic_failure_joannav/archive/2013/10/23/how-to-create-a-custom-list-in-sharepoint-online-quot-w15-quot.aspx

And I'm using this code for trying to create an underlying structure:

using (var clientContext = new ClientContext("https://myEnv.sharepoint.com"))
{
    var passWord = new SecureString();
    foreach (char c in "myPSW".ToCharArray()) passWord.AppendChar(c);

    clientContext.Credentials = new SharePointOnlineCredentials("[email protected]", passWord);
    Web web = clientContext.Web;
    clientContext.Load(web);
    clientContext.ExecuteQuery();
    var folder = CreateFolder(clientContext.Web, "Shared1", "FolderA/SubFolderA/SubSubFolderA");
}

/// <summary>
/// Create Folder client object
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <param name="fullFolderUrl"></param>
/// <returns></returns>
public static Folder CreateFolder(Web web, string listTitle, string fullFolderUrl)
{
    if (string.IsNullOrEmpty(fullFolderUrl))
        throw new ArgumentNullException("fullFolderUrl");
    var list = web.Lists.GetByTitle(listTitle);
    return CreateFolderInternal(web, list.RootFolder, fullFolderUrl);
}

private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderUrl)
{
    var folderUrls = fullFolderUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    string folderUrl = folderUrls[0];
    var curFolder = parentFolder.Folders.Add(folderUrl);
    web.Context.Load(curFolder);
    web.Context.ExecuteQuery();

    if (folderUrls.Length > 1)
    {
        var subFolderUrl = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
        return CreateFolderInternal(web, curFolder, subFolderUrl);
    }
    return curFolder;
}

public static Folder GetFolder(Web web, string fullFolderUrl)
{
    if (string.IsNullOrEmpty(fullFolderUrl))
        throw new ArgumentNullException("fullFolderUrl");

    if (!web.IsPropertyAvailable("ServerRelativeUrl"))
    {
        web.Context.Load(web, w => w.ServerRelativeUrl);
        web.Context.ExecuteQuery();
    }
    var folder = web.GetFolderByServerRelativeUrl(web.ServerRelativeUrl + fullFolderUrl);
    web.Context.Load(folder);
    web.Context.ExecuteQuery();
    return folder;
}

And upon the execution I get this error:

Unhandled Exception: Microsoft.SharePoint.Client.ServerException: List 'Shared1'
 does not exist at site with URL 'https://myEnv.sharepoint.com'.
   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream res
ponseStream)
   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
   at SharepointFolderRename.Program.CreateFolderInternal(Web web, Folder parent
Folder, String fullFolderUrl) in \\vmware-host\shared folders\Documents\Visual S
tudio 2012\Projects\Trunk2015\SharepointFolderRename\Program.cs:line 84
   at SharepointFolderRename.Program.Main(String[] args) in \\vmware-host\shared
 folders\Documents\Visual Studio 2012\Projects\Trunk2015\SharepointFolderRename\
Program.cs:line 49

This is a print of the list in SP. Print of the list

What am I missing?

Upvotes: 1

Views: 4425

Answers (2)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

The reason why you are getting those errors is related with incorrect web url specified. While your list exists on sub site Shared1, you are trying to access it on root site,the below picture illustrates it

enter image description here

So, the solution would be to initialize client context for the proper web site, so replace:

using (var clientContext = new ClientContext("https://myEnv.sharepoint.com/"))
{
    //...
}

with

using (var clientContext = new ClientContext("https://myEnv.sharepoint.com/Shared1"))
{
    //...
}

It is assumed that you want to ctreate folders for list located on Shared1 sub site

Example

The example below demonstrates how to create the folder hierarchy in Documents library under News sub site: (https://contoso.sharepoint.com/news)

   Archive
   |
   2009
      |
      09  

Usage

using (var ctx = GetContext("https://contoso.sharepoint.com/news", userName, password))
{
      var list = ctx.Web.Lists.GetByTitle("Documents");
      var folder = list.CreateFolder("Archive/2015/09");
      Console.WriteLine(folder.ServerRelativeUrl);
}

where

public static ClientContext GetContext(Uri webUri, string userName, string password)
{
   var securePassword = new SecureString();
   foreach (var ch in password) securePassword.AppendChar(ch);
   return new ClientContext(webUri) { Credentials = new SharePointOnlineCredentials(userName, securePassword) };
}

ListExtensions.cs file:

using System;
using Microsoft.SharePoint.Client;

namespace SharePoint.ClientExtensions
{
    public static class ListExtensions
    {


        /// <summary>
        /// Create Folder in List
        /// </summary>
        /// <param name="list"></param>
        /// <param name="folderUrl"></param>
        /// <returns></returns>
        public static Folder CreateFolder(this List list, string folderUrl)
        {
            if (string.IsNullOrEmpty(folderUrl))
                throw new ArgumentNullException("folderUrl");
            if (!list.IsPropertyAvailable("RootFolder"))
            {
                list.Context.Load(list.RootFolder);
                list.Context.ExecuteQuery();
            }
            return CreateFolderInternal(list.RootFolder,folderUrl);
        }

        private static Folder CreateFolderInternal(Folder parentFolder, string folderUrl)
        {  
            var folderUrlParts = folderUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            var curFolder = parentFolder.Folders.Add(folderUrlParts[0]);
            parentFolder.Context.Load(curFolder);
            parentFolder.Context.ExecuteQuery();
            if (folderUrlParts.Length > 1)
            {
                var subFolderUrl = string.Join("/", folderUrlParts, 1, folderUrlParts.Length - 1);
                return CreateFolderInternal(curFolder, subFolderUrl);
            }
            return curFolder;
        }
    }
}

Upvotes: 1

Diogo
Diogo

Reputation: 176

You need to load the list in the CreateFolder method.

public static Folder CreateFolder(Web web, string listTitle, string fullFolderUrl)
{
    if (string.IsNullOrEmpty(fullFolderUrl))
        throw new ArgumentNullException("fullFolderUrl");
    var list = web.Lists.GetByTitle(listTitle);
    clientContext.Load(list);
    clientCOntext.Execute();
    return CreateFolderInternal(web, list.RootFolder, fullFolderUrl);
}

Upvotes: 1

Related Questions