8

I have to all files from one folder another folder using CSOM and C# Thanks for your replay Huge Wood

my code is below

var targetSite = new Uri("https://hello.com//teams/Worldwide_Site");
            string src = @"/teams/Worldwide_Site/Shared Documents/BI/Reports/march";
            string dest = @"/teams/Worldwide_Site/Shared Documents/BI/Reports/April";
            string lst = "Reports";

            MoveFiles(targetSite, lst, src, dest);

public static void MoveFiles(Uri url, string listTitle, string srcFolder,string destFolder)
        {

            using (var context = new ClientContext(url))
            {
                var login = "hello.com";
                var password = "xyz";
                var securePassword = new SecureString();
                foreach (char c in password)
                {
                    securePassword.AppendChar(c);
                }
                context.Credentials = new SharePointOnlineCredentials(login, securePassword);
                var srcList = context.Web.Lists.GetByTitle(listTitle);
                var qry = CamlQuery.CreateAllItemsQuery();
                qry.FolderServerRelativeUrl = srcFolder;
                var srcItems = srcList.GetItems(qry);
                context.Load(srcItems, icol => icol.Include
                    (i => i.FileSystemObjectType,
                        i => i.File));
                context.ExecuteQuery();

                foreach (var item in srcItems)
                {
                    if (item.FileSystemObjectType == FileSystemObjectType.File)
                    {
                        var destFileUrl = string.Format("{0}/{1}/{2}", listTitle, destFolder, item.File.Name);
                        item.File.MoveTo(destFileUrl, MoveOperations.Overwrite);
                        context.ExecuteQuery();
                    }
                }
            }
        }

I'm getting the issue in context.ExecuteQuery error like Folder "April" is not found as per my understood destination path is not correct but where I did wrong?

1
  • Hi Sriven, are you able to expand on this into a proper question please.
    – Hugh Wood
    Commented Apr 24, 2014 at 8:52

3 Answers 3

5

In order to move the single file to the specified destination URL use File.MoveTo method.


There is no built-in method in SharePoint CSOM API for moving Folder with Files from one location into another.

The following solution demonstrates how to move files from source folder into destination folder:

public static class FolderExtensions
{


    public static void MoveFilesTo(this Folder folder, string folderUrl)
    {
        var ctx = (ClientContext)folder.Context;
        if (!ctx.Web.IsPropertyAvailable("ServerRelativeUrl"))
        {
            ctx.Load(ctx.Web, w => w.ServerRelativeUrl);   
        }
        ctx.Load(folder, f => f.Files, f => f.ServerRelativeUrl, f => f.Folders);
        ctx.ExecuteQuery();

        //Ensure target folder exists
        ctx.Web.EnsureFolder(folderUrl.Replace(ctx.Web.ServerRelativeUrl, string.Empty));
        foreach (var file in folder.Files)
        {
            var targetFileUrl = file.ServerRelativeUrl.Replace(folder.ServerRelativeUrl, folderUrl);
            file.MoveTo(targetFileUrl, MoveOperations.Overwrite);
        }
        ctx.ExecuteQuery();

        foreach (var subFolder in folder.Folders)
        {
            var targetFolderUrl = subFolder.ServerRelativeUrl.Replace(folder.ServerRelativeUrl,folderUrl);
            subFolder.MoveFilesTo(targetFolderUrl);
        }
    }

}

static class WebExtensions
{
    /// <summary>
    /// Ensures whether the folder exists   
    /// </summary>
    /// <param name="web"></param>
    /// <param name="folderUrl"></param>
    /// <returns></returns>
    public static Folder EnsureFolder(this Web web, string folderUrl)
    {
        return EnsureFolderInternal(web.RootFolder, folderUrl);
    }


    private static Folder EnsureFolderInternal(Folder parentFolder, string folderUrl)
    {
        var ctx = parentFolder.Context;
        var folderNames = folderUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
        var folderName = folderNames[0];
        var folder = parentFolder.Folders.Add(folderName);
        ctx.Load(folder);
        ctx.ExecuteQuery();

        if (folderNames.Length > 1)
        {
            var subFolderUrl = string.Join("/", folderNames, 1, folderNames.Length - 1);
            return EnsureFolderInternal(folder, subFolderUrl);
        }
        return folder;
    }
}

Key points:

  • allows to ensure whether destination folder(s) exists
  • In case of nested folders, its structure is preserved while moving files

Usage

var srcFolderUrl = "/news/pages";
var destFolderUrl = "/news/archive/pages";
using (var ctx = new ClientContext(url))
{      
    var sourceFolder = ctx.Web.GetFolderByServerRelativeUrl(srcFolderUrl);
    sourceFolder.MoveFilesTo(destFolderUrl);
    sourceFolder.DeleteObject(); // delete source folder if nessesary
    ctx.ExecuteQuery();
}
4

The biggest challenge with this application is that the client OM is very limited when it comes to moving documents, and because the need exists to move documents across site collections we can’t take advantage of the MoveTo methods.

See this blog(SharePoint 2010 : Using The Client Object Model To Move Files And Folders Across Site Collections And Subsites) for detail

public static void CopyDocuments(string srcUrl, string destUrl, string srcLibrary, string destLibrary, Login _login)
    {
        // set up the src client
        SP.ClientContext srcContext = new SP.ClientContext(srcUrl);
        srcContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
        srcContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);

        // set up the destination context (in your case there is no needs to create a new context, because it would be the same library!!!!)
        SP.ClientContext destContext = new SP.ClientContext(destUrl);
        destContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
        destContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);

        // get the list and items
        SP.Web srcWeb = srcContext.Web;
        SP.List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
        SP.ListItemCollection col = srcList.GetItems(new SP.CamlQuery());
        srcContext.Load(col);
        srcContext.ExecuteQuery();

        // get the new list
        SP.Web destWeb = destContext.Web;
        destContext.Load(destWeb);
        destContext.ExecuteQuery();

        foreach (var doc in col)
        {
            try
            {
                if (doc.FileSystemObjectType == SP.FileSystemObjectType.File)
                {
                    // get the file
                    SP.File f = doc.File;
                    srcContext.Load(f);
                    srcContext.ExecuteQuery();

                    // build new location url
                    string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + f.Name;

                    // read the file, copy the content to new file at new location
                    SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
                    SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
                } 

                if (doc.FileSystemObjectType == SP.FileSystemObjectType.Folder)
                {
                    // load the folder
                    srcContext.Load(doc);
                    srcContext.ExecuteQuery();

                    // get the folder data, get the file collection in the folder
                    SP.Folder folder = srcWeb.GetFolderByServerRelativeUrl(doc.FieldValues["FileRef"].ToString());
                    SP.FileCollection fileCol = folder.Files;

                    // load everyting so we can access it
                    srcContext.Load(folder);
                    srcContext.Load(fileCol);
                    srcContext.ExecuteQuery();

                    foreach (SP.File f in fileCol)
                    {
                        // load the file
                        srcContext.Load(f);
                        srcContext.ExecuteQuery();

                        string[] parts = null;
                        string id = null;

                        if (srcLibrary == "My Files")
                        {
                            // these are doc sets
                            parts = f.ServerRelativeUrl.Split('/');
                            id = parts[parts.Length - 2];
                        }
                        else
                        {
                            id = folder.Name;
                        }

                        // build new location url
                        string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + id + "/" + f.Name;

                        // read the file, copy the content to new file at new location
                        SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
                        SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
                    }
                }
            }
            catch (Exception ex)
            {
                Log("File Error = " + ex.ToString());
            }
        }
    }
1
  • this is a great function, ty Commented Jul 20, 2017 at 0:02
0

I got the same 'folder not found' issue when using this approach

item.File.MoveTo(destFileUrl, MoveOperations.Overwrite);

When i get the file object using GetFileByServerRelativeUrl method it works fine

File fileItem = web.GetFileByServerRelativeUrl(item["FileRef"].ToString());
context.Load(fileItem);
context.ExecuteQuery();

string sourceFolder = item["FileDirRef"].ToString();
string targetFilePath = item["FileRef"].ToString().Replace(sourceFolder, destinationFolder);
fileItem.MoveTo(targetFilePath, MoveOperations.Overwrite);

context.ExecuteQuery();

I know it's old thread but i just got the same issue and managed to resolve it. So i would like to share.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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