We had a discussion amongst the developers in our group recently: what is an SPSite, what is an SPWeb, and what is the difference? Which once should I work with in my code? Looking at MSDN for the SPSite class, we see this description:
SPSite Represents a collection of sites on a virtual server, including a top-level site and all its subsites. Each SPSite object, or site collection, is represented within an SPSiteCollection object that consists of the collection of all site collections on the virtual server.
Mmmmm… ooo-kay… what does that mean?
The SPWeb class simply says:
Represents a SharePoint Web site.
Wow. Enlightening. Looking back to my first experiences working with the SharePoint object model in WSS2/SPS2003, I must say this was one of the more confusing points for me. And it’s easy to see why it can be such a confusing/frustrating experience for developers working with the API for the first time. Now that I’ve worked with WSS3/MOSS code more closely, specifically with Publishing Sites where there are many child “sites”, I’ve come to understand the world of SPSite and SPWeb objects.
The problem lies with the difference in terms used between the SharePoint user-interface and the object model. When we are speaking to end-users, they are familiar with the term “creating SharePoint team sites”. However, everytime you create a “site” from the UI, an SPWeb object was created.
It doesn’t help that the MSDN documentation uses the following type of naming conventions in their code samples:
SPSite mySiteCollection = new SPSite("http://servername/");
SPWeb mySite = mySiteCollection.AllWebs["Site_Name"];
SPWeb myRootSite = mySiteCollection.RootWeb;
For me, it would have been much clearer if they wrote something like this instead:
SPSite mySite = new SPSite("http://servername/");
SPWeb myWeb = mySite.AllWebs["Site_Name"];
SPWeb myRootWeb = mySite.RootWeb;
While the description for SPSite may be valid, a typical SharePoint application web site only has one top-level site collection. Therefore, in this url http://servername/site1/site1a/, there are actually three SPWeb objects, and only one SPSite object.
SPSite site1 = new SPSite("http://servername/site1/");
SPSite site1a = new SPSite("http://servername/site1/site1a/");
bool sitesAreEqual = site1.Equals(site1a); // sitesAreEqual should evaluate to true.
SPWeb web1 = site1.OpenWeb();
SPWeb web1a = site1a.OpenWeb();
SPWeb rootWeb = site1.RootWeb; // or site1a.RootWeb; would return same instance.
See the SPSite.OpenWeb() method for more examples: http://msdn2.microsoft.com/en-us/library/ms474633.aspx.
SPSite itself is not a “collection” in the sense that comes from CollectionBase, for example. In fact, both SPSite and SPWeb inherit directly from System.Object. Therefore, to use a name such as mySiteCollection is confusing/misleading.
The key thing to keep in mind is that as developers, we need to use the technically accurate terms when speaking with each other (even if MSDN doesn’t), and reserve the marketing/UI terms when speaking with people who would never see the object model. (Note: there are examples of these kinds of terminology differences all over the place in SharePoint 2007.)
I hope this clears things up a bit…if you find something that is not correct/accurate, please let me know!