7

How do I convert this into Client Object Model, please. I have no full SP installed on the Machine.

I just need the list of sites and subsites in the Given URL..

public List<String> GetAllSites(string spURL)
        {
            IList<String> sites = new List<String>();
            try
            {
                 SPSite oSiteCollection = new SPSite(spURL);
                SPWebCollection collWebsite = oSiteCollection.AllWebs;
                for (int i = 0; i < collWebsite.Count; i++)
                {
                    using (SPWeb oWebsite = collWebsite[i])
                    {
                        SPListCollection collList = oWebsite.Lists;

                        for (int j = 0; j < collList.Count; j++)
                        {
                            sites.Add(collWebsite[i].Title + collList[j].Title);
                        }
                    }
                }
                return sites.ToList();
            }
            catch (Exception ex)
            {
                log.Error(ex.StackTrace + ex.Message);
                return sites.ToList();
            }
        }
12

somthing on the lines of:

     static string mainpath = "http://triad102:1001";
     static void Main(string[] args)
     {
         getSubWebs(mainpath);
         Console.Read();
     }
     public static  void  getSubWebs(string path)
     {          
         try
         {
             ClientContext clientContext = new ClientContext( path );
             Web oWebsite = clientContext.Web;
             clientContext.Load(oWebsite, website => website.Webs, website => website.Title);
             clientContext.ExecuteQuery();
             foreach (Web orWebsite in oWebsite.Webs)
             {
                 string newpath = mainpath + orWebsite.ServerRelativeUrl;
                 getSubWebs(newpath);
                 Console.WriteLine(newpath + "\n" + orWebsite.Title );
             }
         }
         catch (Exception ex)
         {                

         }           
     }

http://social.msdn.microsoft.com/Forums/sharepoint/en-US/284b5f9c-104e-4cbb-8d59-757274f075c5/get-all-subsites-under-site-collection-by-sharepoint-2010-client-object-model?forum=sharepointdevelopmentprevious

code principle is the same, instead of continually talking to the server your sending out one request and returning the data, then you look through the data.... the code above removes the need for many calls as its querying the current site from the url to return once... once you have it loop through and print to screen:

             clientContext.Load(oWebsite, website => website.Webs, website => website.Title);
             clientContext.ExecuteQuery();
  • This one only gets sites within a single site collection. Doesn't get all sites in all site collections – Nicholas DiPiazza Dec 3 '17 at 22:15
5

Since SharePoint CSOM does not support the loading of sites within site collection, the following example demonstrates how to accomplish it:

public static class SiteExtensions
{
    public static List<Web> EnumAllWebs(this Site site, params  Expression<Func<Web, object>>[] retrievals)
    {
        var ctx = site.Context;
        var rootWeb = site.RootWeb;
        ctx.Load(rootWeb, retrievals);
        var result = new List<Web>();
        result.Add(rootWeb);
        EnumAllWebsInner(rootWeb, result, retrievals);
        return result;
    }

    private static void EnumAllWebsInner(Web parentWeb, ICollection<Web> result, params  Expression<Func<Web, object>>[] retrievals)
    {
        var ctx = parentWeb.Context;
        var webs = parentWeb.Webs;
        ctx.Load(webs, wcol => wcol.Include(retrievals));
        ctx.ExecuteQuery();
        foreach (var web in webs)
        {
            result.Add(web);
            EnumAllWebsInner(web, result, retrievals);
        }
    }
}    

Then, your example could be converted into this one:

using (var ctx = new ClientContext(webUri))
{
     var result = new List<string>();
     var webs = ctx.Site.EnumAllWebs(w => w.Title,w => w.Lists);
     foreach (var web in webs)
     {
        foreach (var list in web.Lists)
        {
            result.Add(web.Title + list.Title);
        }
     }
}
  • I used your code, but I'm getting "The request uses too many resources" error in the "EnumAllWebsInner" function. This is how I call the function "var webs = EnumurateSubWebs.EnumAllWebs(ctx.Site, w => w.Title, w => w.Lists, w => w.HasUniqueRoleAssignments, w => w.WebTemplate, w => w.Url, w => w.Id, w => w.ParentWeb);" How to resolve it.? – Karthik Jaganathan Aug 18 '16 at 5:50
  • I get 401 errors when trying to call this code... yet I am a site collection admin ? – Nicholas DiPiazza Dec 3 '17 at 22:15
0

Pretty much the same idea, but you have to load and executequery between every call to the Sharepoint model

Here you can find general information http://msdn.microsoft.com/en-us/library/office/fp179912.aspx

This almost does the job. http://chennaisharepointtraining.blogspot.in/2011/11/get-all-subwebs-using-client-object.html

0

I have tried all these ideas above. They don't work for me. You can use Soap to do it. First call /_vti_bin/SiteData.asmx with this soap web service payload which will get the VirtualServer ContentDatabase entry for the server:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
   <soapenv:Header/>
   <soapenv:Body>
      <soap:GetContent>
         <soap:objectType>VirtualServer</soap:objectType>
         <soap:retrieveChildItems>true</soap:retrieveChildItems>
         <soap:securityOnly>false</soap:securityOnly>
      </soap:GetContent>
   </soapenv:Body>
</soapenv:Envelope>

You can then take that Content Database entry and send another GetContent soap request to get a list of all sites. Example:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
   <soapenv:Header/>
   <soapenv:Body>
      <soap:GetContent>
         <soap:objectType>ContentDatabase</soap:objectType>
         <soap:objectId>{952cf00a-81af-440c-bd7c-5e91d15ac75d}</soap:objectId>
         <soap:retrieveChildItems>true</soap:retrieveChildItems>
         <soap:securityOnly>false</soap:securityOnly>
      </soap:GetContent>
   </soapenv:Body>
</soapenv:Envelope>

The result will have the list of all top level sites.

What permissions do you need to call this? See https://social.msdn.microsoft.com/Forums/sharepoint/en-US/ed50103c-d552-4a9c-8151-b6404650e71d/list-all-top-level-site-collections-in-sharepoint-2013-getting-401-unauthorized-when-calling?forum=sharepointgeneralprevious

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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