Subscribe
E-mail
Download View Codeplex Project Site
Powered by: newtelligence dasBlog 1.9.7174.0
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Rich Finn
dasBlog MOSS template
We've been working on this one for a while, and it's been driving us nuts...
In the current project we're working on, we haven't been able to add any new web parts to pages, nor have we been able to edit the properties on the existing ones. When we do, we've been seeing the three following errors:
- Cannot save the property settings for this Web Part. Exception occurred. (Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION))- Unable to add selected web part(s). Exception occurred. (Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION))- Unable to add selected web part(s). List View Web Part could not be added, list may be hidden.
Even stranger was that it was only occurring in the root web of the current site collection.
In researching the 0x80020008 error when related to web parts, the few people that have found anything have said that it could be caused by disposal of the SPContext.Current.Site or SPContect.Current.Web objects. We looked all over our code and didn't find that we were doing that anywhere.
We switched the master page back to the default.master, and we could add and edit web parts without any issues, so we then started whittling down the server controls on the custom master page until we found three custom server controls that were present when the web part errors occur. Taking a closer look, these three controls all had the following lines in common.
using (SPWeb rootWeb = SPContext.Current.Site.RootWeb) { //code }
Commenting out of the code caused the errors to go away. What's going on here?
Turns out that there's something that the Best Practices: Using Disposable Windows SharePoint Services Objects post and Roger Lamb's SharePoint 2007 and WSS 3.0 Dispose Patterns by Example should point out a little clearer. If you look at the bottom of Roger's post, there's a comment by Stephen Kaye where he hits the nail on the head:
If your current context’s web is the root web of you current context’s site then the RootWeb property of the site will reference the same object return by SPControl.GetContextWeb and SPContext.Current.Web and should therefore not be disposed.
So, this means that if you are in the root web of your site collection, and you dispose of SPContext.Current.Site.RootWeb, you're actually disposing of SPContext.Current.Web. Not good.
Here's how we changed the code to ensure that we could use the RootWeb SPWeb object, but not dispose it if the SPContext.Current.Web is the RootWeb:
SPWeb rootWeb = null; if (SPContext.Current.Web.IsRootWeb) rootWeb = SPContext.Current.Web; else rootWeb = SPContext.Current.Site.RootWeb; //code if (!SPContext.Current.Web.IsRootWeb) rootWeb.Dispose();