The Black Knight Sings

Songs about SharePoint and other adventures by Per Jakobsen


Date: # Monday, July 14, 2008

Title: FeatureReceiver To Cleanup WebPart Files


Many web-part developers are surprised to see that their web-parts are listed as available even though they have deactivated the feature which contains them

And the users are equally surprised when they then try to add the web-part only to see it fail because the code (and safe-control entry) has been removed.

The problem comes from the fact that deactivating a Feature doesn't remove files provisioned using Module and File entries

The solution is quiet simple:
Just make a feature receiver which deletes all the .webpart files in the FeatureDeactivating event. You can even get all the files to delete from the xml-files associated with the feature so the following code does it all automatically:

   18         public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

   19         {

   20             using (SPSite site = properties.Feature.Parent as SPSite)

   21             {

   22                 RemoveWebParts(site, properties.Definition);

   23             }

   24         }

   25 

   26         private void RemoveWebParts(SPSite site, SPFeatureDefinition definition)

   27         {

   28             using (SPWeb web = site.RootWeb)

   29             {

   30                 string wpcatalogUrl = SPUrlUtility.CombineUrl(web.Url, "_catalogs/wp");

   31 

   32                 // Get the Feature.xml for the feature

   33                 //

   34                 XmlDocument featureXml = new XmlDocument();

   35                 featureXml.LoadXml(definition.GetXmlDefinition(web.Locale).OuterXml);

   36 

   37                 XmlNamespaceManager nsMgr = new XmlNamespaceManager(featureXml.NameTable);

   38                 nsMgr.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/");

   39 

   40                 // Get the Location attribute of each ElementManifest inside each ElementManifests inside the Feature

   41                 //

   42                 foreach (XmlNode locationNode in featureXml.SelectNodes("/sp:Feature/sp:ElementManifests/sp:ElementManifest/@Location", nsMgr))

   43                 {

   44                     // Get the ElementManifest XML

   45                     //

   46                     XmlDocument elementManifest = new XmlDocument();

   47                     elementManifest.Load(Path.Combine(definition.RootDirectory, locationNode.Value));

   48 

   49                     XmlNamespaceManager nsMgr2 = new XmlNamespaceManager(elementManifest.NameTable);

   50                     nsMgr2.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/");

   51 

   52                     // Get the Url attribute of each file in Modules (with List attribute='113' WebPartCatalog

   53                     //

   54                     foreach (XmlNode webPartFileUrl in elementManifest.SelectNodes("/sp:Elements/sp:Module[@List='113']/sp:File/@Url", nsMgr2))

   55                     {

   56                         // Delete the file from the WebPart Catalog

   57                         //

   58                         SPFile wpFile = web.GetFile(SPUrlUtility.CombineUrl(wpcatalogUrl,webPartFileUrl.Value));

   59                         wpFile.Delete();

   60                     }

   61 

   62                 }

   63             }

   64         }

And if you combine this with the code from this post then you get a file like this which works even if the Feature is removed as part of a solution being retracted.



Monday, July 14, 2008 6:02:34 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. And all information or programs are without warranty. Use at your own risk


© Copyright 2008 Send mail to the author(s) Per Jakobsen Feed your aggregator (RSS 2.0)