The Danger in using SPSite.OpenWeb()
June 8th, 2009
Recently I ran into a “feature” of SharePoint’s SPSite.OpenWeb() method (the no argument constructor specifically). If the OpenWeb() method is used with a URL that is not known to exist, it can result in some unexpected behavior.
Assuming you have the following site structure…
- SiteCollection
- Subsite1
- Subsite2
- …
Can you find the bug?
// !!! only use this code in a web part
// to get the SPWeb the web part is currently in !!!
string server = "http://myserver";
string siteUrl = "/sites/SiteCollection/This Subsite Does Not Exist";
using (SPSite site = new SPSite(server + siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
Console.WriteLine(site.Url);
Console.WriteLine(web.Url);
}
}
The problem is on line #9. The URL for the SPWeb that was just opened is the same as the SPSite’s URL: http://myserver/sites/SiteCollection. There is no exception thrown.
The behavior I expected, would be some sort of exception when opening a web that does not exist. Even worse is the fact that no error is thrown; it simply defaults to the top level site collection that exists. This means, you get the wrong SPWeb object.
A better way to get an SPWeb object is (updated 7/13/09 per Rikard’s comment):
// better code to open a web
string server = "http://myserver";
string siteUrl = "/sites/SiteCollection";
string subSite = "This Subsite Does Not Exist";
using (SPSite site = new SPSite(server + siteUrl))
{
using (SPWeb web = site.OpenWeb(subSite))
{
if (web.Exists)
{
// do work with the web...
Console.WriteLine(site.Url);
Console.WriteLine(web.Url);
}
}
}
This code should be able to safely open a web at any location. Keep in mind, trying to access any of the properties of a web that does not exist will result in:
System.IO.FileNotFoundException: There is no Web named “/sites/SiteCollection”.
Again, the exception is not thrown in the constructor, but when attempting to access the SPWeb’s properties… such as web.Url.

July 13th, 2009 at 7:35 am
I agree that this is an unfortunate oversight in the framework. However, you can use the web.Exists property directly after opening a the SPWeb-object to be sure that the object is valid.
July 13th, 2009 at 9:29 am
Thanks for the comment Rikard. I updated my post to include checking the web.Exists property. I think that is definitely a better way than getting an exception.