Wednesday, July 18, 2007

Trying to use a closed/disposed webpart.

Coming from a C++ background, I am a stickler for making sure my objects are disposed. I also know that cetain SP objects are extremely heavy, and should always be tossed when you are done with them. These objects include SPWeb and SPSite.

An error I know some developers run into is "Trying to use an SPWeb object that has been closed or disposed and is no longer valid." Let me try to shed some light on this, and also point out the correct way to create these objects.

There are 2 common ways to get our hands on an SPWeb object. One way is to use the SPSite.OpenWeb() method and the other is to use the SPContext.Current.Web method. Both of these methods will return to you the current Web, but the difference is that OpenWeb will return a Web object in a different memory space and CurrentWeb will return the Web object using the current memory space and thread.

As .net 2.0 developers, we are told to wrap our disposable objects in Using clauses, or (correctly) to use try/finally. The problem is that when you dispose of the SPWeb object after you gained a pointer to it from the SPContext, you are disposing of the object being used to render the page. Seldomly, Sharepoint recovers from the error, and goes on it's merry way. But more likely, the page will not render, and you will get the error.

As a best practice, if I am only going to fetch and display data, I use the SPContext object and do not dispose of the object, and when I plan on modifying or changing data, I use OpenWeb and dispose.

We all know that SharePoint tries to cover errors, and if a webpart function catches the error, but does not display it, then you can run into a situation where a container page is failing for an unknown reason. Your best bet is to try to add/remove the webparts on the page until the offensive webpart is discovered.

My friend Eric Stallworth points out that Microsoft covers this in this article

1 comment:

AfterWeb said...

I rid out my error because of your blog, good man