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.

2 Responses to “The Danger in using SPSite.OpenWeb()”

  1. Rikard Says:

    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.

  2. Kit Says:

    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.

Leave a Reply