Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

Until today I had been using the Using statement to open and dispose of webs.

The variable relative_web_url is defined by a user input in the custom web part editor.

    using (SPWeb web = SPContext.Current.Site.OpenWeb(relative_web_url); {


    }

What I found though was that sometimes the web opened in the using was either SPContext.Current.Web or SPContext.Current.RootWeb and that the automatic disposing of these webs as you would suspect would lead to errors in the logs.

I then conjured this method which only disposes of the web if it isn't in the SPContext.Current object.

    SPWeb web = null;
    try
    {
        web = SPContext.Current.Site.OpenWeb(relative_web_url);

    }
    catch (Exception exception)
    {

    }
    finally
    {
        if (web != null && web.ID != SPContext.Current.Web.ID && web.ID != SPContext.Current.Site.RootWeb.ID)
            web.Dispose();
    }

Is this a good solution? Am I doing this all wrong? Is there a better way to open webs that may or may not be in SPContext.Current object.

share|improve this question
add comment

3 Answers 3

SPContext.Current.Site.OpenWeb(relative_web_url) won't ever be the same as the current context. It might be a second SPWeb object that corresponds to the same site as the current context, but it's not the same actual object instance, so it's always safe to dispose of (and important to always dispose of) the SPWeb object returned from every call to OpenWeb.

Now, if you have a method that accepts an SPWeb object as a parameter, and you don't know if it's the current context or the result of a call to OpenWeb, then you shouldn't be disposing of it ever, the caller of that method (or some other caller further up the chain) should be responsible for disposing of it.

share|improve this answer
add comment

You are not disposing of the actual site, even in the same context. The rule is, if you create a web using new (or .OpenWeb() ), it must be disposed of. If you use the system object, so SPContext.Current.Web, it must not be disposed.

Here is an in-depth description of how and when to dispose.

So... to summarize, this is what to do with SPContext.Current:

SPWeb web = SPContext.Current.Web;

And here is what to do with a web made by a url string:

using(SPSite site = new SPSite(MyWebUrl))
{
    using(SPWeb web = site.OpenWeb())
    {
         //stuff
    }
}
share|improve this answer
add comment

So, it is likely you are getting the following error in ULS;

Disposable type not disposed Microsoft.SharePoint.SPWeb

Per the following blog, I'd alternatively suggest you do the following:

using (SPSite site = new SPSite("http://your-url"))
{
    SPWeb web = site.RootWeb;
    // No explicit web dispose required
}  // siteCollection automatically disposed by implementing using()
// web will be Disposed by SPSite

I'd also suggest for finding your disposable issues, I'd download SPDisposeCheck, it will tell you as you build your solutions if any items aren't getting disposed properly.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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