Dienstag, 4. Oktober 2011

Error occurs while trying to upgrade installed features of an upgraded solution

It’s way back since my last post, but at last I found something very useful to post.

During the process of developing on a SharePoint 2010 solution, to have clean presuppositions for testing and avoid phantom mistakes I very often create new site collections and delete them afterwards. A part of this process is also removing and adding newer versions of the solutions to the solution-store. So from time to time I was confronted with strange error messages when I tried to upgrade features to new versions.

I concretely tried to do it the Microsoft recommended way and used a modified version of the program, you can find here: http://msdn.microsoft.com/en-us/library/ff798298.aspx

The program that iterates over the SPWebApplication to find upgradable features sometimes fails with an error message that says that it can’t find a special SiteCollection: The site with the id D0D529C1-DC06-4DB0-A8A3-81466E1E75DB could not be found.
This is true because it has been previously deleted by me and is no longer available in Central Administration or anywhere else. It seems, there are still some SiteCollection-related artifacts in the content database stored that prevent a clean upgrading of the new versioned features.

Have a look at the Default TimerJobs,  the promisingly entry “Gradual Site Delete”, we perhaps can use to solve this issue with tools out of the box. By default it’s executed daily but we can change the cycle to earlier executions or even start it manually.

This blog described its functionality as “Deletes all the data from the host content database for all deleted site collections”. What a pitty, in my case, it doesn’t. The error remains.

Now it’s time to have a look at the content database. The name of this table looks encouraging: dbo.SiteDeletion

After opening the table, an entry appears that includes the evil SiteId, which seems to be the crux of the matter:

Luckily Microsoft gave us the method ForceDeleteSite on the SPContentDatabase-class.

If you write a really short program, for e.g. a console application that takes the Uri to get the SPWebApplication-object and the Guid of the corrupted SiteCollection, you can create a new entry to the database-table with a datetime of 1900-01-01.

Simply, there are only those two lines needed:

SPWebApplication spWebApplication = SPWebApplication.Lookup(new Uri("http://mywebapplication")); // insert the webapplication

spWebApplication.ContentDatabases[0].ForceDeleteSite(new Guid("D0D529C1-DC06-4DB0-A8A3-81466E1E75DB"), true, false); // insert the ID from the errormessage

After that, retry running the “Gradual Site Delete”-timerjob and – surprise – both entries are deleted.

If you retry upgrading your feature, no more annoying error message occurs.