How to detect when a Sharepoint file is in a subfolder

时间:2016-08-31 16:47:50

标签: c# sharepoint

I'm displaying files from a Sharepoint 2010 document library on my web page. I'm successfully showing a list of the files and their icons. However, some of the files are in subfolders, and instead of showing the file icon, I'd like to show a folder icon.

How do I detect when a file is in a subfolder?

I could parse each file's ServerRelativeUrl to determine the folder structure. I'm hoping there is another way.


Here is the Sharepoint library:

library


And here is the code which produces the list of files in that library:

using (ClientContext clientContext = new ClientContext(SharepointSite))
    {
        var query = new CamlQuery
        {
            ViewXml = "<View Scope='RecursiveAll'>" +
                        "<Query>" +
                         "<Where>" +
                            "<Eq>" +
                               "<FieldRef Name='FSObjType' />" +
                               "<Value Type='Integer'>0</Value>" +
                            "</Eq>" +
                         "</Where>" +
                        "</Query>" +
                      "</View>"
        };

        var sourceList = clientContext.Web.Lists.GetByTitle("Test Library");
        var files = sourceList.GetItems(query);
        clientContext.Load(files);
        clientContext.ExecuteQuery();
        foreach (var file in files)
        {
            var id = file.Id;
            var filename = file["FileLeafRef"].ToString();
            var iconName = clientContext.Web.MapToIcon(filename, string.Empty, IconSize.Size16);
            clientContext.ExecuteQuery();
            var imgUrl = "http://sharepointsite/_layouts/images/" + iconName.Value;
            Image iconImage = new Image {ImageUrl = imgUrl};

            clientContext.Load(file.ParentList);
            clientContext.ExecuteQuery();
            var listUrl = file.ParentList.DefaultDisplayFormUrl;
            HyperLink docLink = new HyperLink
            {
                Text = filename,
                NavigateUrl = listUrl + "?ID=" + id //ToDo:  fix
            };

            HtmlTableRow row = new HtmlTableRow();
            HtmlTableCell cell1 = new HtmlTableCell();
            cell1.Controls.Add(iconImage);
            HtmlTableCell cell2 = new HtmlTableCell();
            cell2.Controls.Add(docLink);
            row.Cells.Add(cell1);
            row.Cells.Add(cell2);
            tbFiles.Rows.Add(row);
        }
    }

which results in:

files

Only the first file in the list is actually in the top-most library. The rest are in "Test Folder".

1 个答案:

答案 0 :(得分:3)

It might helpful to understand the available options for the view scope property of your CAML query:

  • Default: Gets files and subfolders from a specific folder
  • RecursiveAll: Gets files and subfolders from all folders
  • FilesOnly: Gets only files (no folders) from a specific folder
  • Recursive: Gets only files (no folders) from all folders

If you want to maintain a hierarchical folder structure, you have two options:

  1. Get all files in the library (using a view scope of Recursive or RecursiveAll) and try to reconstruct the file structure yourself by post-processing the results
  2. Get only files and folders from one folder at a time (using a view scope of Default), executing a new query whenever you want to drill down into the contents of a subfolder

Both approaches are equally valid, but in general I'd recommend the second. They both have their downsides: the first requires a larger up-front network request and more post-processing logic to assemble the hierarchy, while the second requires multiple network requests to retrieve all the data.

If taking the second approach, you can limit your CAML query to a specific folder by setting the CamlQuery's FolderServerRelativeUrl property to the URL of the desired folder. When working with the items retrieved from a specific folder, you can check their FileSystemObjectType property to determine if they are files or folders; if they are folders you can access their Folder property to get the associated folder object, from which you can get the ServerRelativeUrl property to use in your next query to get items from that folder.