locked
How can I get a list of all subsites of a particular subsite? RRS feed

  • Question

  • How can I get a list of all subsites of a particular subsite?

    nonam
    Wednesday, April 22, 2009 7:23 PM

Answers

  • You can use the SPWeb.Webs property. That gets you a Web site collection object that represents all Web sites immediately beneath the Web site, excluding children of those Web sites.
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.webs.aspx
    using(SPSite site = new SPSite("http://yoursiteurl"))
    {
        using(SPWeb web = site.OpenWeb())
        {
            SPWebCollection subWebs = web.Webs;

        }

    }


    You can also use the SPSite.AllWeb property. That gets you the collection of all Web sites that are contained within the site collection, including the top-level site and its subsites.
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsite.allwebs.aspx
    using(SPSite site = new SPSite("http://yoursiteurl"))
    {
        SPWebCollection allWebs = site.AllWebs;


    }

    If you want to get all the sub sites of a sub site including the sub sites of those sub sites (huh?) you would have to use the first example and iterate through every web that comes up to get it's children. Keep in mind that for a large number of sub sites that can get pretty slow..


    Mirjam --http://www.sharepointblogs.com/mirjam
    • Marked as answer by jmillman Thursday, April 23, 2009 1:13 PM
    Wednesday, April 22, 2009 7:42 PM
  • Do you dispose of the subwebs in the foreach loop as well?

    foreach (SPWeb subweb in web.Webs)

    {
        try
        {
            //some code
        }
        finally
        {
            if (subweb != null)
            subweb.Dispose();
        }

    }


    Mirjam --http://www.sharepointblogs.com/mirjam
    • Marked as answer by jmillman Thursday, April 23, 2009 1:13 PM
    Wednesday, April 22, 2009 8:34 PM

All replies

  • You need a recursive loop.

    Something along the lines of:
            private static void GetImmediateChildren(SPWeb parent, ref List<SPWeb> subSites)
            {
                subSites.Add(parent);
                if (parent.Webs.Count == 0)
                {
                    return;
                }
                foreach (SPWeb immediateChild in parent.Webs)
                {
                    GetImmediateChildren(immediateChild, ref subSites);
                }
            }
    Just an example. You would probably need a collection that you pass into this method as a reference and add the webs as you go along.
    Visit my blog http://jasear.wordpress.com
    Wednesday, April 22, 2009 7:29 PM
  • Thanks, but isn't an spweb always the root site?  I want the subsites of a subsite

    so if I have
    root
      >Departments
        >>Dept1
        >>Dept2

    I want to pass in departments and get back dept1 and dept2.

    I was at first looping on the web.allwebs and filtering, but I am getting a ton of errors and I think it is a memory issue.
    nonam
    Wednesday, April 22, 2009 7:32 PM
  • The AllWebs property is on an SPSite object which represents your Site Collection.

    Every Site Collection has a RootWeb which is an SPWeb object. Under your RootWeb you can have a complex hierarchy of SPWebs. So each subsite in the SharePoint API is represented as an SPWeb. So your Dept1 and Dept2 are SPWebs but they fall below the Departments SPWeb.

    You need to do something similar to the code I wrote above. If you just need the immediate children then you dont need a recursive method simply getting the SPWeb.Webs property returns you the collection of immediate subsites. However if you need the whole structure of SPWebs below a certain SPWeb then you need a recursive method.

    Hope this makes sense.


    Visit my blog http://jasear.wordpress.com
    Wednesday, April 22, 2009 7:41 PM
  • You can use the SPWeb.Webs property. That gets you a Web site collection object that represents all Web sites immediately beneath the Web site, excluding children of those Web sites.
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.webs.aspx
    using(SPSite site = new SPSite("http://yoursiteurl"))
    {
        using(SPWeb web = site.OpenWeb())
        {
            SPWebCollection subWebs = web.Webs;

        }

    }


    You can also use the SPSite.AllWeb property. That gets you the collection of all Web sites that are contained within the site collection, including the top-level site and its subsites.
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsite.allwebs.aspx
    using(SPSite site = new SPSite("http://yoursiteurl"))
    {
        SPWebCollection allWebs = site.AllWebs;


    }

    If you want to get all the sub sites of a sub site including the sub sites of those sub sites (huh?) you would have to use the first example and iterate through every web that comes up to get it's children. Keep in mind that for a large number of sub sites that can get pretty slow..


    Mirjam --http://www.sharepointblogs.com/mirjam
    • Marked as answer by jmillman Thursday, April 23, 2009 1:13 PM
    Wednesday, April 22, 2009 7:42 PM
  • Thanks a lot guys, webs is exactly what I am looking for.  I don't care about nested subsites at all.

    By the way, the reason I am doing this is because even though I have been extremely careful with my disposal, I have been having problems and I think it is due to the way I was referencing sites.

    One more quick followup.

    Is there a way to get rid of my first using statement and create a web directly?  I am afraid that the spsite is where my memory problem is.

     

    using (SPSite site = new SPSite("http://site/" + siteName))

     

    using (SPWeb web = site.OpenWeb("/" + siteName))
    foreach(spweb subwebs in web.webs)


    nonam
    Wednesday, April 22, 2009 8:20 PM
  • I dont think the first using statement would cause a memory leak. The only other way of getting an SPWeb is to get it from the SPContext object or from other objects such as an SPList e.t.c.

    I dont think either of them will be much use to you in this scenario. Do you have lots and lots of Webs in your SiteCollection? I think that is probably where your problem lies.


    Visit my blog http://jasear.wordpress.com
    Wednesday, April 22, 2009 8:26 PM
  • Do you dispose of the subwebs in the foreach loop as well?

    foreach (SPWeb subweb in web.Webs)

    {
        try
        {
            //some code
        }
        finally
        {
            if (subweb != null)
            subweb.Dispose();
        }

    }


    Mirjam --http://www.sharepointblogs.com/mirjam
    • Marked as answer by jmillman Thursday, April 23, 2009 1:13 PM
    Wednesday, April 22, 2009 8:34 PM
  • Yes, I have a ton of them.

    I read some article that said that if you call web.parent that it actually puts a copy in memory.

    Now I am just using some top level sites, then grabbing subsites from those and ignroing the rest.  I think that it will work much better.
    nonam
    Wednesday, April 22, 2009 8:35 PM