Saturday, March 28, 2009

Benefits for KWizCom Customers

If you are a KWizCom customer you can recieve the free add-on of your choice!

Here's how:

+ Send us 3 high resolution screenshots depicting how you implemented KWizCom add on/s in your organization.
+ Write a sentence or two describing the solution you implemented and the benefit you gained from your add on
+ Send us your company logo – make sure it's high resolution!

The best screenshots and quotes will appear in a KWizCom slideshow displayed at this year's
UK SharePoint Best Practices Conference.

In addition - each customer who submits screenshots and quotes will qualify to choose one KWizCom add on free of charge!

You gain:
+ Free promotion of your organization – boost your image as a sophisticated, technologically advanced organization
+ Free KWizCom add-on of your choice!

Your investment – 1 email

This special, onetime offer expires Tuesday March 31st!

Send your screenshots to: forest@kwizcom.com

Be sure to specifiy which add-on you have chosen!

Thursday, March 12, 2009

SPException: Trying to use a SPWeb object that has been closed or disposed and is no longer valid

Ever seen this error? See if it sounds familiar…

Just about any developer working long enough with SharePoint will, at some point, wake up in the middle of the night with the words "Memory Leak" echoing in through their head... No - it is not the cat's fault, and no it does not mean you forgot to take out the trash again... What did happen? You came across one of Microsoft's "best practices" articles regarding disposing of SPWeb and SPSite objects in SharePoint…

According to the original MS guidance, every SPWeb or SPSite object you create (or get) that was not initiated within the page's context (i.e. not SPContext.Current.Web and not SPControl.GetContextWeb(Context) ) must be disposed of.

It used to be that the "using" statement construct was recommended to avoid forgetting to dispose… in other cases you'd put up a flag and dispose of it at the end of your code's life cycle - either way was good enough.

Being the "good guys" that we are, we went over and updated all of our codes and components to match these guide lines.
And what happened? Every once in a while disposing these objects would cause baffling errors such as: "Trying to use a SPWeb object that has been closed or disposed and is no longer valid".

But hey, if we call SPContext.Current.Site.RootWeb - the best practices guidelines said we have to dispose of it! Same goes for SPContext.Current.Web.Site and SPContext.Current.Web.Site.RootWeb etc.

Recently I came across a great article by Roger Lamb showing a few updates from Microsoft regarding these disposable objects and recommendations.

So - pay close attention to these updates… it just might help you sleep through the night!

* When making a call to SPContext.Current.Web.Site.RootWeb - you now have to dispose only of the SPSite object: SPContext.Current.Web.Site!

Basically, you should NOT dispose of the SPSite.RootWeb object directly.

* When calling SPWeb.ParentWeb - you should NOT dispose of the ParentWeb object!

* Same goes to SPList.ParentWeb - do NOT dispose of the SPWeb object.

Other updates I found interesting (and frustrating) are:
* Calling SPWeb.AllWebs collection requires you to dispose of this collection object.
* Creating a new site by SPWeb.Webs.Add() - need to dispose of the web object returned.
* Calling GetLimitedWebPartManager() method? It will create a SPWeb object of its own and not dispose of it properly.

Please review the complete updated best practices guide at MSDN here:
http://msdn.microsoft.com/en-us/library/aa973248.aspx

I hope Microsoft will release an update for this issue soon.. Just thinking of all the code lines I wrote under the wrong best practices article is making me dizzy...

Good luck and happy disposing!

Shai Petel.

=~=~= Update =~=~=
Ok, this explains why it took me so long to find this problem...
I had this code in my web part, written according to the original best practices:
using(SPSite site = SPContext.Current.Web.Site)
{
    using(SPWeb web = site.RootWeb)
    {
        //Some code here...
    }
}

I cannot explain this but I only got this error on some sites, and on others it worked OK. Strange huh?
What I found is that this code will throw exception on any team site I created within a site collection that is not in the web application root path (i.e. sites under http://server/sites/*).

Anyway - according to the new guidelines, I should not dispose of the RootWeb object in this case. If I dispose of the SPSite object - it disposes of the RootWeb object -in this case my context web object...
So I updated my code to something like this and it worked:
SPWeb web = SPContext.Current.Site.RootWeb;//No disposing
//Some code here...

Sunday, March 1, 2009

Search Results

By Sveta Yerpilev - SharePoint Technical Consultant

KWizCom Professional Services – www.kwizcom.com

A client of mine once requested that I change the look and feel of their search results page. The client was a large company that had decided to change the design of their SharePoint portal. The portal had a search center which was where I needed to make the change.

This is how I did it:

First of all I needed a Core Results Web Part. You can add a web part to your results page from the Web Parts Gallery or use the SharePoint web part that is automatically added to each search results page.

Next I had to setup the fields (columns) I wanted to see in the search result. To do so - open the properties of the Core results web part and under the Results Query Options change the Selected Columns xml text. To add a new column you need add this text to the xml before tag:


Save the changes and now you can start to redesign the look and feel of the search results. The fastest way to do this is to use the XML of the search results. To access the XML you need to add this code instead of the XSLT code of the web part in the XSL Editor:



Save your changes and do a test search. You will get an XML code of the search results. Copy this code and paste it to notepad. Save the file on your desktop and open SharePoint Designer. Connect to one of your SharePoint sites and create a new blank ASPX page. After this go in to the design mode of your page and add a new DataView Web Part. In the Data Source details choose the XML files and add a new XML file. In the new opened window browse to the file you saved before and import it to SharePoint Designer.

Once you perform this operation you'll see your file in the XML files section. Click on this file and press "Show Data".

Now you will be able to design your Data View Web Part however you want, using columns from the Search Results XML file. You will also be able to perform sorting/filtering/grouping on your search results but keep in mind that each function will create results only on the page you are currently using. In other words, if you sort your search results by site title the grouping will group the content of your current search results page.

After you finish designing your page you the only thing left you need to do is copy the entire code from your page, between the tags and , and paste it to the XSL Editor of the Core Results Web Part. Save your changes and verify that everything works by doing a test search. If you like the look of your search results page you can delete the temp ASPX page from your SharePoint site and delete the search results XML file.





If you would like more information on customizing a search results page I suggest this insightful article by Tobias Zimmergren:
http://www.zimmergren.net/archive/2008/03/15/moss-2007-customize-the-search-result-using-xslt-part-3-customize-using-sharepoint-designer-2007.aspx

SharePoint gives you many options for customizing your search results.

You can define different search results pages for each search scope you run.

You can set a specific search results page on the server level and redirect all search results to that page.

You can even define a search results page for a Search Box Web Part - it will redirect all search results (not including the Contextual Search Scope Search results) to the page you defined.

If you create a new Search Center you may want to redirect all search queries to the Search Center search results page.

You can setup this function on the scopes level or in the Search Settings of the root site in your Site Collection.

I hope this article (and the first two parts of this series) on SharePoint search results has been helpful to you. Please continue to visit the KWizCom blog for more helpful information, SharePoint tips and "how to" guides. We are here to help!