C# sharepoint l oop через все файлы в папке и все подпапки - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь l oop после всех файлов в папке и всех подпапках так же глубоко, как это идет из первой папки. Я нашел способ, но я думаю, что это глупо и, вероятно, является лучшим способом сделать это.

Код перебирает первую папку и все файлы. После этого он снова зацикливает подпапки, затем файлы и снова в третий раз.

Есть ли другой способ сделать это? просто выберите одну папку, и она автоматически завершит иерархию.

static void ReadAllSubs(string siteUrl, string siteFolderPath, string localTempLocation)
        {
            ClientContext ctx = new ClientContext(siteUrl);
            ctx.AuthenticationMode = ClientAuthenticationMode.Default;
            SecureString passWord = new SecureString();
            string pwd = "xxx";
            foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);
            ctx.Credentials = new SharePointOnlineCredentials("test@test.com", passWord);
            FolderCollection folderCollection = ctx.Web.GetFolderByServerRelativeUrl("Delte%20dokumenter/07 - Detaljprosjekt").Folders;
            // Don't just load the folder collection, but the property on each folder too
            ctx.Load(folderCollection, fs => fs.Include(f => f.ListItemAllFields));
            // Actually fetch the data
            ctx.ExecuteQuery();



            foreach (Folder folder in folderCollection)
            {
                //LOOP MAIN FOLDER
                Console.WriteLine("---------------FIRST LAYER FOLDER---------------------");
                var item = folder.ListItemAllFields;
                var folderpath = item["FileRef"];
                FolderCollection LoopFolder = ctx.Web.GetFolderByServerRelativeUrl(folderpath.ToString()).Folders;
                ctx.Load(LoopFolder, fs => fs.Include(f => f.ListItemAllFields));
                ctx.ExecuteQuery();
                Console.WriteLine(folderpath);


                //LOOP ALL FILES IN FIRST MAIN FOLDER
                FileCollection mainfiles = ctx.Web.GetFolderByServerRelativeUrl(folderpath.ToString()).Files;
                ctx.Load(mainfiles);
                ctx.ExecuteQuery();
                Console.WriteLine("---------------FIRST LAYER FILES---------------------");
                foreach (File mainfile in mainfiles)
                    {
                        Console.WriteLine(mainfile.Name);
                        Console.WriteLine(mainfile.MajorVersion);
                    }

                //LOOP SUBFOLDER
                Console.WriteLine("---------------SECOUND LAYER FOLDER---------------------");
                foreach (Folder ff in LoopFolder)
                {

                    var subitem = ff.ListItemAllFields;
                    var folderpathsub = subitem["FileRef"];
                    Console.WriteLine(folderpathsub);

                    //LOOP ALL FILES IN FIRST SUBFOLDER
                    FileCollection files = ctx.Web.GetFolderByServerRelativeUrl(folderpathsub.ToString()).Files;
                    ctx.Load(files);
                    ctx.ExecuteQuery();
                    Console.WriteLine("---------------SECOUND LAYER FILES---------------------");
                    foreach (File file in files)
                    {
                        Console.WriteLine(file.Name);
                        Console.WriteLine(file.MajorVersion);
                    }
                    var created = (DateTime)item["Created"];
                    var modified = (DateTime)item["Modified"];



                    Console.WriteLine("---------------THIRD LAYER FOLDER---------------------");
                    FolderCollection ThirdLoopFolder = ctx.Web.GetFolderByServerRelativeUrl(folderpathsub.ToString()).Folders;
                    ctx.Load(ThirdLoopFolder, fs => fs.Include(f => f.ListItemAllFields));
                    ctx.ExecuteQuery();
                    foreach (Folder fff in ThirdLoopFolder)
                    {
                        var item3 = fff.ListItemAllFields;
                        var folderpath3 = item3["FileRef"];
                        Console.WriteLine(folderpath3);

                        //LOOP ALL FILES IN THIRD SUBFOLDER
                        FileCollection thirdfiles = ctx.Web.GetFolderByServerRelativeUrl(folderpath3.ToString()).Files;
                        ctx.Load(thirdfiles);
                        ctx.ExecuteQuery();
                        Console.WriteLine("---------------THIRD LAYER FILES---------------------");
                        foreach (File file in thirdfiles)
                        {
                            Console.WriteLine(file.Name);
                            Console.WriteLine(file.MajorVersion);
                        }

                    }
                }
            }
        }

1 Ответ

1 голос
/ 20 апреля 2020

Я могу предложить два решения.


Первый метод

Первый - это рекурсивный подход, аналогичный Вашему решению.



    private static void UseRecursiveMethodToGetAllItems()
    {
        using (var context = new ClientContext(WebUrl))
        {
            context.Credentials = new SharePointOnlineCredentials(UserName, Password);

            var rootFolders = context.Web.GetFolderByServerRelativeUrl(LibName).Folders;
            context.Load(rootFolders, folders => folders.Include(f => f.ListItemAllFields));
            context.ExecuteQuery();
            foreach (var folder in rootFolders)
            {
                GetFilesAndFolders(context, folder);
            }

            Console.ReadLine();
        }
    }

    private static void GetFilesAndFolders(ClientContext context, Folder folder)
    {
        if (folder != null && folder.ListItemAllFields.FieldValues.Count > 0)
        {
            Console.WriteLine($"Folder - {folder.ListItemAllFields.FieldValues["FileLeafRef"]}");

            var fileCollection = folder.Files;
            context.Load(fileCollection, files => files.Include(f => f.ListItemAllFields));
            context.ExecuteQuery();

            foreach(var file in fileCollection)
            {
                Console.WriteLine($" -> {file.ListItemAllFields.FieldValues["FileLeafRef"]}");
            }

            var subFolderCollection = folder.Folders;
            context.Load(subFolderCollection, folders => folders.Include(f => f.ListItemAllFields));
            context.ExecuteQuery();
            foreach (var subFolder in subFolderCollection)
            {
                GetFilesAndFolders(context, subFolder);
            }
        }
    }


первая функция выполняет аутентификацию в указанный WebUrl и получает папки из папки root (которая является названием библиотеки). Тогда второй метод является рекурсивным. Сначала получает все файлы из текущей папки и печатает их на консоли, после чего следующим шагом является запрос вложенных папок в этой папке, а затем выполнить тот же метод.

Я создал библиотеку образцов с папками и файлами, и результатом вышеупомянутого метода является enter image description here


Второй метод

Второй метод немного более «плоский». Можно создать запрос CAML, чтобы рекурсивно получить все элементы из библиотеки, а затем проверить, является ли он файлом или папкой. Все элементы имеют свойство path для определения иерархии.



    private static void UseQueryToGetAllItems()
    {
        using (var context = new ClientContext(WebUrl))
        {
            context.Credentials = new SharePointOnlineCredentials(UserName, Password);
            List<ListItem> result = new List<ListItem>();

            try
            {
                ListItemCollectionPosition position = null;
                int page = 1;
                do
                {
                    List list = context.Web.Lists.GetByTitle(LibName);
                    CamlQuery query = new CamlQuery();

                    query.ViewXml = new StringBuilder()
                        .Append("<View Scope=\"RecursiveAll\">")
                        .Append("<Query>")
                        .Append("")
                        .Append("</Query>")
                        .Append("<RowLimit>5000</RowLimit>")
                        .Append("</View>")
                        .ToString();

                    query.ListItemCollectionPosition = position;
                    ListItemCollection items = list.GetItems(query);
                    context.Load(items);
                    context.ExecuteQuery();

                    position = items.ListItemCollectionPosition;
                    if (items.Count > 0)
                        result.AddRange(items);

                    context.ExecuteQuery();
                    page++;
                }
                while (position != null);

                result.ForEach(item =>
                {
                    Console.WriteLine($"{item["ID"]}) Path: {item["FileDirRef"]} - Name: {item["FileLeafRef"]} - Type: {item.FileSystemObjectType}");
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadLine();
        }
    }


Этот метод также выполняет проверку подлинности для той же библиотеки, а затем выполняет запрос для получения всех элементов в списке (запрос выполняется в пагинации способ преодоления порогового значения для получения более 5000 элементов в запросе). После того, как метод получает список всех элементов, он распечатывает их, представляя путь, имя файла и тип (файл или папка ... или другое .. Если хорошо помните, в этом перечислении могут быть также сеть и некоторые другие).

Для той же библиотеки, что и первый метод. Результатом этого подхода является

enter image description here


надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...