2013년 3월 11일 월요일

Treeview Recursive trawl using the SP Client Object Model

Recursive trawl using the SP Client Object Model


Here’s a simple example of SP2010’s managed Client Object Model being used to build up a TreeView of subsites and lists, for a given site. 

I’m using WinForms just to show the concept, if you’d like to recreate it, simply create a form and insert a TreeView control (called tv1), and a Label (called label1). Don’t forget to add a reference to Microsoft.SharePoint.Client as well.

Screen Shot 2011-09-13 at 2.43.16 PM

Optionally comment out the “Short Version” and uncomment the Long - This additional code goes an extra level, i.e. it iterates through the items of each list. Bear in mind this will slow down considerably, and there is also the 5000 row List Threshold limit to take into account. 

I had expected File Size to be a property in the COM (let me know if it is!) but I just couldn’t find anything related. This means we’re still stuck with dealing with CAML / Internal Names, etc. when it comes to bringing these back, e.g. File_x0020_Size :(

Check out MSDN’s Using the SharePoint Foundation 2010 Managed Client Object Model as a good starting point. The way Linq is used to ‘queue up’ only the relevant list properties we’re after, and filter the list collection to ignore hidden lists is pretty neat, makes for very simple / brief code.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Microsoft.SharePoint.Client;

namespace WindowsFormsApplication1
{
    public partial class Form1 : System.Windows.Forms.Form
    {
        private SPItems items = new SPItems();

        public Form1()
        {
            InitializeComponent();

            items.ItemAdded += new SPItems.OnItemAdded(items_ItemAdded);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            new Thread(() =>
            {
                using (ClientContext clientContext = new ClientContext("http://mysite”))
                {
                    clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
                    clientContext.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

                    var web = clientContext.Web;

                    ProcessWeb(clientContext, web, new Guid());
                }

                tv1.Invoke(new Action(() =>
                {
                    tv1.Nodes.Add(items.getTreeNodeCollection());
                    tv1.Nodes[0].Text = "Site Structure";
                    tv1.SelectedNode = tv1.Nodes[0];
                    tv1.ShowNodeToolTips = true;
                    tv1.ExpandAll();
                }));

            }).Start();
        }

        protected void items_ItemAdded(object sender, SPItem i)
        {
            label1.Invoke(new Action(() => label1.Text = i.Title));
        }

        private void ProcessWeb(ClientContext c, Web web, Guid parentID)
        {            
            c.Load(web);
            c.Load(web.Lists, lists => lists.Include(l => l.Title, 
                                                    l => l.Id, 
                                                    l => l.DefaultViewUrl,
                                                    l => l.ParentWebUrl).Where(l => !l.Hidden));
            c.Load(web.Webs);
            c.ExecuteQuery();

            items.AddItem(new SPItem() { ID = web.Id, 
                                         ParentID = parentID, 
                                         Title = web.ServerRelativeUrl });

            foreach (List l in web.Lists)
            {
                /* SHORT VERSION */

                items.AddItem(new SPItem()
                {
                    ID = l.Id,
                    ParentID = web.Id,
                    Title = l.Title
                });

                /* END SHORT VERSION  */
                
                /* LONG VERSION - Iterates through every listitem to get file size */

                //var cml = new CamlQuery() { ViewXml = @"<View><ViewFields><FieldRef Name='File_x0020_Size' /></ViewFields><Query></Query></View>" };
                //var lic = l.GetItems(cml);

                //try
                //{
                //    c.Load(lic);
                //    c.ExecuteQuery();

                //    long totalSize = 0;
                //    long totalItems = 0;

                //    foreach (ListItem li in lic)
                //    {
                //        if (li.FieldValues.Keys.Contains("File_x0020_Size"))
                //        {
                //            long size = 0;

                //            if (long.TryParse(li.FieldValues["File_x0020_Size"].ToString(), out size))
                //                totalSize += size;
                //        }

                //        totalItems++;
                //    }

                //    items.AddItem(new SPItem()
                //    {
                //        ID = l.Id,
                //        ParentID = web.Id,
                //        Title = l.Title,
                //        ItemCount = totalItems,
                //        ItemSizeBytes = totalSize
                //    });
                //}
                //catch (Exception exc)
                //{
                //    Debug.WriteLine("EXCEPTION: " + exc.Message);
                //}

                /* END LONG VERSION - Iterates through every listitem to get file size */
            }

            foreach (Web sub in web.Webs)
            {
                try
                {
                    ProcessWeb(c, sub, web.Id);
                }
                catch (Exception exc)
                {
                    Debug.WriteLine("EXCEPTION: " + exc.Message);
                }
            }
        }
    }

    public class SPItems : List<SPItem>
    {
        public delegate void OnItemAdded(object sender, SPItem i);
        public event OnItemAdded ItemAdded;

        public void AddItem(SPItem item)
        {
            this.Add(item);
            ItemAdded(this, item);
        }

        public TreeNode getTreeNodeCollection()
        {
            var n = new TreeNode();
            
            foreach (SPItem o in this)
            {
                if (o.ParentID == new Guid())
                    n.Nodes.Add(getNode(o));
                else
                {
                    var found = n.Nodes.Find(o.ParentID.ToString(), true);

                    if (found.Length > 0)
                        found[0].Nodes.Add(getNode(o));
                }
            }

            return n;
        }

        private TreeNode getNode(SPItem o)
        {
            return new TreeNode(o.Title)
            {
                Name = o.ID.ToString(),
                ToolTipText = "ITEM COUNT = " + o.ItemCount + Environment.NewLine + "ITEM SIZE = " + o.ItemSizeBytes
            };
        }
    }

    public class SPItem
    {
        public Guid ID { get; set; }
        public Guid ParentID { get; set; }
        public string Title { get; set; }
        public long? ItemCount { get; set; }
        public long? ItemSizeBytes { get; set; }
    }
}

How to get SubSites using client object model





How to get SubSites using client object model 




Try this code to get list of all sub sites
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Utilities;

private static void GetAllSubSites()
{
ClientContext clientContext = new ClientContext(“http://{yoursiteurl}/“);
Web oWebsite = clientContext.Web;
clientContext.Load(oWebsite,
website => website.Webs,
website => website.Title
);
clientContext.ExecuteQuery();
Console.WriteLine(“Available sites Count: ” + oWebsite.Webs.Count);
for (int i = 0; i != oWebsite.Webs.Count; )
{
Console.WriteLine(“Site Title: “+ oWebsite.Webs[i].Title);
}
}

My SharePoint Blog 
http://dhireny.blogspot.com