Applies To: SharePoint 2010
I followed the Microsoft article, Deploying Branding Solutions for SharePoint 2010 Sites Using Sandboxed Solutions and I was able to quickly get the bones of a Branding project put together. Unfortunately, I found that when the solution was deactivated all the files I deployed remained exactly where they were.
I found various solutions for removing your files ranging from individual file lists to marking every file with your feature ID, but for a simple Branding project all you really need to do is:
- Remove usage of your Master Pages from every site referencing them
- Remove your files from the Style Library
- Remove your Master Page files from the Master Page Catalog
The first two can be done in the FeatureDeactivating event handler and the third can be done in the FeatureUninstalling event handler. For those that just want the code, here it is:
Public Overrides Sub FeatureDeactivating(ByVal properties As SPFeatureReceiverProperties) Dim siteCollection As SPSite = CType(properties.Feature.Parent, SPSite) If siteCollection IsNot Nothing Then Dim topSite As SPWeb = siteCollection.RootWeb 'Calculate relative path to site from Web Application root Dim WebAppRelativePath As String = topSite.ServerRelativeUrl If Not WebAppRelativePath.EndsWith("/") Then WebAppRelativePath &= "/" 'Enumerate through each site and remove branding For Each site As SPWeb In siteCollection.AllWebs If Not site.MasterUrl.EndsWith("minimal.master") Then site.MasterUrl = WebAppRelativePath & "_catalogs/masterpage/v4.master" Else site.MasterUrl = WebAppRelativePath & "_catalogs/masterpage/minimal.master" End If If Not site.CustomMasterUrl.EndsWith("minimal.master") Then site.CustomMasterUrl = WebAppRelativePath & "_catalogs/masterpage/v4.master" Else site.CustomMasterUrl = WebAppRelativePath & "_catalogs/masterpage/minimal.master" End If site.AlternateCssUrl = String.Empty site.SiteLogoUrl = String.Empty site.Update() Next 'Kill Style Library Folder Dim styleLibrary As SPList = topSite.Lists.TryGetList("Style Library") If styleLibrary IsNot Nothing Then Dim folders As SPListItemCollection = styleLibrary.Folders Dim item As SPListItem = DirectCast((From i In folders Where DirectCast(i, SPListItem).Url = "Style Library/BSResources" Select i).FirstOrDefault(), SPListItem) item.Delete() End If End If End Sub Public Overrides Sub FeatureUninstalling(ByVal properties As SPFeatureReceiverProperties) Dim siteCollection As SPSite = properties.UserCodeSite If siteCollection IsNot Nothing Then 'Kill Master Pages Dim mpGallery As SPList = siteCollection.GetCatalog(SPListTemplateType.MasterPageCatalog) If mpGallery IsNot Nothing Then Dim mpages As SPListItemCollection = mpGallery.GetItems(New SPQuery With {.Query = "<Where><Or><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>BSmain.master</Value></Eq><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>BSminimal.master</Value></Eq></Or></Where>"}) If mpages IsNot Nothing Then For i As Integer = mpages.Count - 1 To 0 Step -1 mpages(i).Delete() Next End If End If End If End Sub
Wow code! Alright Scriptkitties, copy away! Everyone else, here’s what we’re doing and why:
1. Remove usage of your Master Pages from every site referencing them
After gathering basic information about where the feature was deployed and figuring out the correct reference URLs, we begin looping through every site in the sitecollection and resetting the master page to the defaults beginning in line 11.
We are just undoing what was done in the FeatureActivating event. The only thing of note is that I hate when a Branding solution replaces every MasterPage with theirs and then just blindly restores v4.master. Mostly this is fine, but if one of your subsites is an Enterprise Search site or anything else using the minimal.master you’ve just wrecked it. Obviously if you know you aren’t using minimal.master then you can simplify this section. Also, I always name my minimal.master replacement in the form [Something]minimal.master to ensure this works out.
2. Remove your files from the Style Library
To keep things simple, I keep all of my resource files in a single root folder within the Style Library. Obviously I have subfolders to organize images, fonts, etc. but all of those are within my one folder. This makes finding stuff much easier, but more than that it makes removing the files super easy – Just delete that folder.
Lines 27-33 do just that. After getting a reference to the Style Library (Every sitecollection in SharePoint 2010 has one of these), grab the folder (just replace the “Style Library/BSResources” string in line 31 with your folder path) and delete.
3. Remove your Master Page files from the Master Page Catalog
There are lots of guides for deleting deployed master pages and I didn’t find any that worked. Basically every time I tried to delete a master page from within the FeatureDeactivating event I got an error about them still being used. I’m sure there’s a good reason for this (feel free to let me know in the comments), but it doesn’t really matter because as long as you followed step 1 above, it’ll work in the FeatureUninstalling event.
We simply grab a reference to the sitecollection’s Master Page Gallery and use some simple CAML to grab references to our Master Pages. Then we walk through them and delete them.
That’s it, you now have a self-cleaning solution and you are a responsible member of the SharePoint community.
[…] The Chris Kent Quick Fixes, Workarounds, & Neat Tricks I felt like sharing HomeAbout RSS ← Branding Solution Cleanup […]
Thanks for your Code in Uninstalling Event – thats what i was looking for.
I’ve experienced the same problems concerning the deletion of a custom masterpage – and none of the available “solutions” worked for me neither.
[…] trimming attributes for our controls, we have to edit the MasterPage. If you’re developing a custom branding solution then this should be easy enough to do directly in Visual Studio. If you’re just customizing […]
Very good article. I’m dealing with some of these issues as well..
There’s definately a lot to learn about this topic.
I really like all of the points you’ve made.
Veery nice article. I thoroughly enjoyed it annd
was very informative.
Oh my goodness! Awesome article dude! Many thanks, However I am going through issues with your RSS.
I don’t know why I cannot subscribe to it. Is there anybody else having the same RSS issues?
Anybody who knows the answer can you kindly respond?
Thanks!!