2

我正在使用 Microsoft.Sharepoint.Client 命名空间中的类来处理 sharepoint 站点。当我在 Windows Phone 7 上工作时,我找不到 SPFolderCollection/SPFolder 类。

我需要过滤掉隐藏文件夹和系统文件夹(eg_vti_pvt)​​。

我发现一个例子如下:

// filter the folders like “_catalogs” or “_private”
                if (folder.ParentListId != Guid.Empty)
                {
                    SPList list  = web.Lists[folder.ParentListId];
//filter the folders like “Reporting Templates” or “IWConvertdForms”
                    if (list.Hidden == false)

(示例取自http://go4answers.webhost4life.com/Example/know-spfolder-invisible-visible-27871.aspx)。

但是,由于我没有“SP”类,我无法在 Windows Phone 上实现它(没有 ParentListId 方法)。

任何想法/解决方法将不胜感激。

谢谢你。

PS 请注意,我想不惜一切代价避免使用 CAML;我只需要能够列出和检索文件和文件夹的 url,我不需要使用列表或通知。

更新 所以看来我可以绕过以下限制:

Foldercollection folder_assist = new FolderCollection( WHAT DO I PUT HERE??? );
    ctx.Load(folders);
                ctx.ExecuteQueryAsync(delegate(object sender1, ClientRequestSucceededEventArgs args)
                {
                foreach (Folder f in folders)
                {
                    ctx.Load(f.ParentFolder);
                }
                ctx.ExecuteQuery();
                foreach (Folder f in folders)
                {
                    List ejh;
                     // if we are in the top folder, the .parentfolder may be null
                    if (f.ParentFolder != null && f.ParentFolder.Name != "")
                    {
                        ejh = ctx.Web.Lists.GetByTitle(f.ParentFolder.Name);
                    }
                    else
                    {
                        ejh = ctx.Web.Lists.GetByTitle(f.Name);
                    }
                    ctx.Load(ejh);

                    try
                    {
                        ctx.ExecuteQuery();
                    }
                    catch
                    {
                        ejh = null;
                    }
                    if (ejh != null)
                    {
                        if (ejh.Id != Guid.Empty)
                        {
                            if (ejh.Hidden == false)
                            {
                     folder_assist.Add(f.ServerRelativeURL;
                         }
                        }
                    }
                } 
                win.Dispatcher.BeginInvoke((Action)(() => DO SOME WORK...

            }, delegate(object sender1, ClientRequestFailedEventArgs args)
                {
                   win.Dispatcher.BeginInvoke((Action)(() => MessageBox.Show("something went wrong" + args.ToString())));
                });

我现在遇到的问题是第一行 - 似乎 Microsoft.Sharepoint.FolderCollection 构造函数需要上下文(我拥有并且可以轻松传递)和 ObjectPath 类型,因为我只需要一个占位符来收集所有未隐藏且不特殊的文件夹。

我该如何解决这个问题?

更新 2

好的,很明显的结果,我只是用于List<Folder>fassist。

但是,我注意到还有两件事:

a)我的解决方案的性能相当令人震惊。以前需要一些时间才能获得列表(当我没有在异步线程中过滤时),现在需要 10-20 秒才能获得列表(而且我在服务器上只有少数项目!)。

有什么想法/建议吗?(真正的问题是我不能只将文件夹集合传递回 UI 线程来解析和一一添加,因为我仍然需要为 parentFolder 执行查询。如果我尝试在 foreach() 循环中异步执行此操作UI线程,我得到一个非实例化的对象,因为UI线程不等待查询的执行。如果我使用AutoResetEvent让它等待,UI线程就会被锁定。WP7不允许使用ClientContext.Executequery( ) 在 UI 线程中。太糟糕了。)

b)我访问的每个文件夹中似乎仍然有“表单”文件夹!现在正在努力,但任何想法都将不胜感激。

4

2 回答 2

2

如何使用 SharePoint CSOM 排除“系统”文件夹

选项1

Folder 类公开Folder.ListItemAllFields 属性,该属性指定与文件夹关联的列表项,对于“系统”文件夹,相应的列表项不存在。

以下示例演示如何加载文件夹并验证该文件夹是常规文件夹还是“系统”文件夹:

using (var ctx = new ClientContext(webUri))
{

      var list = ctx.Web.Lists.GetByTitle(listTitle);
      var folder = list.RootFolder;
      ctx.Load(folder);
      ctx.Load(folder.Folders, fcol => fcol.Include(f => f.Name, f => f.ServerRelativeUrl, f => f.ListItemAllFields));
      ctx.ExecuteQuery();
      foreach (var subFolder in folder.Folders)
      {
           bool systemFolder = subFolder.ListItemAllFields.ServerObjectIsNull != null && subFolder.ListItemAllFields.ServerObjectIsNull.Value;
           if(!systemFolder)
              //Process regular Folder...
      }
 }

选项 2

下面演示了通过 SharePoint CSOM 使用 CAML 查询加载文件夹的另一种方法

using (var ctx = new ClientContext(webUri))
{

    var list = ctx.Web.Lists.GetByTitle(listTitle);
    var items = list.GetItems(CamlQuery.CreateAllFoldersQuery());
    ctx.Load(items,icol => icol.Include(i => i.Folder));
    ctx.ExecuteQuery();
    var folders = items.Select(i => i.Folder);
    foreach (var folder in folders)
    {
        //Process folder...
    }
}

关键点:

  • 这种方法的优点是只返回常规文件夹
于 2015-01-06T16:36:26.803 回答
0

类前面没有 SP 的原因是您使用的示例是服务器对象模型,它仅在安装了 SharePoint 的服务器上运行。

您正在使用的 Windows Phone 上的版本是客户端对象模型,并且它在所有类上都没有 SP 前缀。

理想情况下,要回答我需要知道您从哪里获得对文件夹的引用的问题?网站、Web 列表?或者你为什么要枚举文件夹?

FolderCollection 必须来自客户端对象模型中某处的对象。

例如,ctx.Web.Folders 将返回一个您可以枚举的FolderCollection,而不仅仅是创建一个新的FolderCollection。

大多数更高级别的对象(如 Web 和 List)通常具有 .Folders 属性,您可以从中检索文件夹列表,而无需使用 CAML。

您可以尝试使用此代码。

        ClientContext ctx = new ClientContext("http://yoururl");

        var webFolders = ctx.Web.Folders;
        ctx.Load(webFolders);
        ctx.Load(ctx.Web.Folders, folders => folders.Include(folder => folder.ParentFolder));
        ctx.Load(ctx.Web.Folders, folders => folders.Include(folder => folder.Folders));

        ctx.ExecuteQuery();
        foreach (var folder in webFolders)
        {
           // Do stuff here!
        }

它将从 Web 加载所有文件夹(实际上是根文件夹)及其父级和子级。我仍然不知道如何以有效的方式隐藏文件夹。

请参阅我的评论,了解为什么我认为代码运行缓慢。

编辑:

您可以尝试这样做以获取 Web 中的所有文档库。

        var webLists = ctx.Web.Lists;
        ctx.Load(webLists);

        // request that List.RootFolder is returned
        ctx.Load(ctx.Web.Lists, lists => lists.Include(list => list.RootFolder ));
        // request that RootFolder.Folders is returned
        ctx.Load(ctx.Web.Lists, lists => lists.Include(list => list.RootFolder.Folders ));
        // only return lists with a BaseType of 101 (Document Library)
        ctx.Load(ctx.Web.Lists, lists => lists.Where(list => list.BaseTemplate == 101));

        ctx.ExecuteQuery();
        foreach (var list in webLists)
        {
            var rootFolder = list.RootFolder;
            // Do stuff here!
        }
于 2013-03-09T12:22:31.430 回答