Home > sharepoint, webpart > Cleaning up your WebPart Gallery

Cleaning up your WebPart Gallery

Deploying webparts in SharePoint can be difficult (when you are learning) because of the many ways to do it. You can manually add webparts to the WebPart gallery, you can add WebParts through features and you can even manually add them to certain file system folders.

If you have developed extensively in SharePoint, you probably choose the feature way to deploy WebParts. I am not going to go into this conversation right now, but it is well known that the best practice for building webparts is to deploy them with features. However, one thing that nobody really talks about is removing the WebPart from the WebPart Gallery. If a WebPart is placed in the WebPart gallery when the feature is activated, shouldn’t it be removed from the WebPart gallery when the feature is de-activated? In this article we are going to go over the basics of how WebParts are added to the WebPart gallery during activation of the feature and then we are going to show how you can clean up your gallery when the feature is deactivated.

Overview of WebParts and Features

The premise of WebParts is simple – you are adding an xml file to a special list in SharePoint. This special list is called the Web Part Gallery and the xml file you add is called a .webpart file or a .dwp file. The .webpart or .dwp file “describes” the properties of the WebPart and points to a code file where the .net code runs that builds the WebPart controls. If you want to visit this special WebPart Gallery you can go to your SharePoint site and put “/_catalogs/wp” after your url (i.e.: http://server:port/_catalogs/wp). If I have already confused you at this point, you probably want to start looking into some beginner guides to WebParts in SharePoint. I will do a small overview of WebParts in this article (that might be helpful for beginners), but the point of this article is to show some advanced techniques to how to clean up your WebPart Gallery.

When deploying webparts in SharePoint I always use a Feature to deploy the WebPart to the WebPart gallery. Then I always wrap these features up in a WSP solution in order to deploy a single solution to my SharePoint farm. This is best practice and is really easy once you have done it a couple of times. Personally, I choose to use WSPBuilder to build my WSP solutions (but the process is the same if you use Visual Studio Extensions or if you build your WSPs manually).

If you are using WSPBuilder you can just click Add – New Item – WSPBuilder – WebPart Feature. This will create a .webpart file, feature.xml, element.xml  and code file for you. And, I choose “Site” scope so that the WebPart is added to my Site Collection WebPart Gallery. If you don’t use WSPBuilder, the process is the same, you still have to build the .webpart file, feature.xml, element file and code file (WSPBuilder just does it for you).

So, let’s talk about what these files do:

1.       Feature.xml – this file defines “how” the feature will get deployed and the general settings for the feature. Technically, this is the only file required for a feature to work.

 

The important part of this file is the “Scope”. The scope defines where the feature will be deployed (Site, Web, Web Application, Farm). For webparts, we usually choose “Site” in order for the WebPart to be added to the WebPart Gallery. The other important part of this file is the “ElementManifest”. This tells the feature where the element file is located. The element file is the actually actionable file in a feature.

<?xml version=1.0 encoding=utf-8?>

<Feature  Id=7801227a-326a-4a65-8769-6e56ade76b66

          Title=Custom Webpart

          Description=This is my custom webpart Webpart

          Version=12.0.0.0

          Hidden=FALSE

          Scope=Site

          DefaultResourceFile=core

          xmlns=http://schemas.microsoft.com/sharepoint/ >

  <ElementManifests>

    <ElementManifest Location=elements.xml/>  

  </ElementManifests>

</Feature>

 

2.       Elements file – usually we call this file elements.xml, but you can call it whatever you want. You just need to make sure it is an xml file and you need to make sure that the name you call it is the same as the reference in the feature.xml.

 

This file tells SharePoint “what” to do with the feature. There are a lot of different things you can do with SharePoint Features. So, you have to do your research to understand the different xml combinations. In the case of the WebPart, we are using a “Module” action. Module actions move files to different galleries (or lists) in SharePoint. With webparts, we want to move the .webpart gallery to the WebPart gallery list. We do this by setting the “url” property to the “_catalogs/wp” path. That is the path for the WebPart gallery list. The other thing to notice in this file is the “Group” and “QuickAddGroups”. These define the grouping when you click “Add New Webpart” on your SharePoint site.

<?xml version=1.0 encoding=utf-8 ?>

<Elements xmlns=http://schemas.microsoft.com/sharepoint/>

  <Module Name=WebPartPopulation Url=_catalogs/wp RootWebOnly=TRUE>  

         <File Url=CustomWebpart.webpart Type=GhostableInLibrary>

                <Property Name=Group Value=RDA></Property>

                <Property Name=QuickAddGroups Value=RDA />

         </File>    

  </Module>

</Elements>

 

3.        .webpart file – this is the file that “describes” the properties of the WebPart. This could also be a .dwp file (it all depends on the version of the WebPart you are using). SharePoint supports .net webparts and SharePoint webparts. That is why you can have .dwp and .webpart files. So, any property you can set in your WebPart, can be set in this file. I am not going to show an example here because the set of properties is different for every WebPart.

 

This file also contains the assembly path to the code file. This is important, because if you ever change information about the Code file (name, version, etc…), then you need to change the path in your .webpart file.

 

4.       Code file – this is the file that actually runs the webpart code. These files inherit from one of two classes depending on the version of WebPart you are building (.net webpart or SharePoint webpart). For example, a .net framework webpart will inherit from Microsoft.SharePoint.WebPartPages.WebPart. Once again, I am not going to show an example of this, because it is different for every customization. The basis of this class is that you build out your html controls programmatically and add them to the Control collection.

 

Side Note: On a side note that is not really part of this article, don’t think the SharePoint webpart (i.e.: dwp) is better to use than the .net webpart (i.e.: .webpart) just because one is labeled a SharePoint webpart. If you don’t plan on using SharePoint webpart connections or part caching, I actually recommend using a .net webpart in SharePoint. Also, you might hear .dwp webparts referred to as Version 2 webparts and .webparts referred to as Version 3 webparts. This is because .dwp webparts were originally built just for SharePoint 2.0 and are backwards compatible. But, in SharePoint 3.0 we got the ability to use the asp.net webparts.

 

Cleaning up your WebPart Gallery

Ok, so you know how to deploy a WebPart to the WebPart Gallery. But, you notice that when you de-activate your Feature the WebPart is still hanging around in the Gallery. Some developers don’t really care about this. But, other than the obvious problem of keeping a clean Gallery for maintaince, there is another big issue. Let’s say you are using versioning for your assembly for the WebPart code. The reference for the assembly is located in the .webpart file. Thus, if you don’t remove the WebPart from the gallery before you make version changes, then your new assembly version will never make it to the gallery.

So, the easiest way to do this is to just go to the WebPart Gallery and remove it before you install and activate your updated feature. However, as most SharePoint developers know, you want to stay away from manual processes as much as possible. That makes your customizations almost impossible to maintain as your code base grows.

But, the answer to this problem is easy. Create a feature receiver to remove the webpart from the WebPart Gallery when the feature deactivates. I saw this done for the first time when I was reviewing the code for the Forms Based Authentication project in the Community Toolkit for SharePoint:  http://www.codeplex.com/CKS. I modified the code a little to meet my needs, but it is basically the same. Here is how you do it.

Create a Generic Class

This class is a generic class that will work for any WebPart feature receiver. The idea behind this class is to implement the Feature Deactivating event and remove the WebPart. Here is the code for this class:

     class GenericWebPartFeatureReceiver : SPFeatureReceiver

    {

 

        /// <summary>

        /// Remove the webpart from the webpart gallery. This is to fix a shortcoming of SharePoint

       ///       that it doesn’t remove

        /// the webpart when the feature gets deactivated (even though it adds it when the feature

       ///       gets activated).

        /// </summary>

        /// <param name=”properties”></param>

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

        {

            SPSite site = null;

            try

            {

                site = properties.Feature.Parent as SPSite;

                using (SPWeb web = site.RootWeb)

                {

                    SPList list = web.Lists[“Web Part Gallery”];

 

                    // go through the items in reverse

                    for (int i = list.ItemCount – 1; i >= 0; i–)

                    {

                        // format name to look like a feature name

                        string webpartName = list.Items[i].Name;

                        webpartName = webpartName.Substring(0, webpartName.IndexOf(‘.’));

 

                        // delete web parts that have been added

                        if (properties.Feature.Definition.DisplayName == webpartName)

                        {

                            list.Items[i].Delete();

                            break;

                        }

                    }

                }

            }         

            finally

            {

                if (site != null)

                    site.Dispose();

            }

        }

 

        public override void FeatureActivated(SPFeatureReceiverProperties properties){ }

 

        public override void FeatureInstalled(SPFeatureReceiverProperties properties){ }

 

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { }

    }

 

Call Feature Receiver

After your Generic Feature Receiver is built, then you just need to call it from the feature.xml file for all your WebParts. Here is some sample code. It is the same as the feature.xml file I showed above, except for the fact that I placed a reference to a RecieverAssembly and a ReceiverClass.

<?xml version=1.0 encoding=utf-8?>

<Feature  Id=7801227a-326a-4a65-8769-6e56ade76b66

          Title=Custom Webpart

          Description=This is my custom webpart Webpart

          Version=12.0.0.0

          Hidden=FALSE

          Scope=Site

          DefaultResourceFile=core

          xmlns=http://schemas.microsoft.com/sharepoint/

   ReceiverAssembly=MySolution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3cbe19ecf7353dae

   ReceiverClass=MySolution.GenericWebPartFeatureReceiver>

  <ElementManifests>

    <ElementManifest Location=elements.xml/>  

  </ElementManifests>

</Feature>

Note: You cannot just copy the xml above. The reference to the features ReceiverAssembly and ReceiverClass is specific to my implementation. When you deploy the assembly that contains the “GenericWebPartFeatureReceiver” to your BIN or GAC, then you need to get the information necessary to build out these two lines. Make sure the name of the Assembly and Namespaces match your implementation. And, make sure that the PublicKeyToken matches your public key for your assembly.

 

That’s it; you now have a Generic WebPart Feature Receiver that will remove the WebPart from the WebPart Gallery whenever your WebPart Feature is deactivated. This should help you keep your gallery clean and will help eliminate possible issues with assembly versioning.

Advertisements
Categories: sharepoint, webpart
  1. April 14, 2009 at 11:13 pm

    Greg – Thanks for posting. I found this very helpful. I took the Generic Feature Receiver a step further by having it inspect the Feature’s element definitions for the WebPart names, thus eliminating the assumption that the WebPart has the same name name as the Feature. Feel free to take a look here.

  2. Chris
    April 22, 2009 at 4:13 pm

    Great article. I know that Feature Receiver works when doing a GAC deployment. Can you also apply the Feature Receiver mechanism by doing a BIN deployment?

  3. Greg Galipeau
    April 22, 2009 at 4:19 pm

    I do not believe it is possible to utilize a feature receiver and the BIN. Unless someone knows of some sort of workaround I am not aware of. However, this question has come up multiple times on the MSDN forum and the consensus so far is that it is not possible.

  4. Goddard
    July 3, 2009 at 4:16 pm

    Man, your tips changed my life. Seriously, keep this coming and thank you so much.

  5. July 6, 2009 at 4:01 pm

    @Chris: You can apply a feature receiever to web parts deployed to the bin folder, but the receiver itself has to live in the GAC. You’ll need to build two projects to create two wsp files and have one deploy to the GAC (with your receiver) and one deploy to the bin (with your web part) then make the web part feature dependant on the receiver feature and hide the feature receiver. The feature reciever will automatically activate (because it’s hidden) and the web part feature won’t activate unless the reciever is in place. Do all your cleanup in your feature receiever and you can continue to deploy your web part via xcopy to the bin directory.

  6. Chris Speck
    July 27, 2009 at 1:32 pm

    I’ve not had an issue with deploying the receiver to the bin. My Web Parts are all in a single assembly deployed to bin. I added similar code to cleanup the .webpart files to a feature receiver in the same assembly, and it works fine.

  7. September 16, 2009 at 9:16 am

    Hi Greg,
    a very helpful article for every webpart developer. A few days ago I stumpled on that kind of problem when looking at a customers sharepoint installation.
    I just wanted to write an article for my sharepoint blog when I found your article.
    Very good work – I just wrote a few lines in german about the problem and recommended reading your article for the details.
    Regards,
    Oliver
    http://shrepointblogs.com/blogs/owwirkus

  8. Biju
    September 24, 2009 at 6:25 am

    Hi,
    I have a webpart(already deployed) called RegisterEventHandler.webpart, which i have deleted from the SPListCollection

    SPSite siteCollection = SPContext.Current.Site;
    using (SPWeb siteRootWeb = siteCollection.RootWeb)
    {
    list = siteRootWeb.Lists[“Web Part Gallery”];
    if (list.Items[i].DisplayName.Equals(“RegisterEventHandler”))
    {
    list.Items[i].Delete();
    break;
    }
    }

    Could you please suggest me how to populate the webpart again into the gallery programatically?
    (http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/57010779-edb9-42fa-a217-b0dedbe1deb6)

    With regards

    Biju

  9. Biju
    October 1, 2009 at 8:50 am

    Hi ,

    I felt that the information which i had given in my previous query was not so clear, so i am explaining it in more detail.

    Basically I have an event handler class (inheriting SPItemEventReceiver) and a Feature class(inheriting SPFeatureEventReceiver) as a feature in my project. I have also added an webpart in the same project. This webpart will be used to register my event handler to any particular list ie., in the webpart the user enters the name of the list which needs to be registered to the EventHandler and click a button which does the job.

    On deploying the feature (.wsp) using the STSADM command the feature and the web part gets deployed sucessfully. On deployment the webpart gets populated automatically in the web part gallery.

    On deactivating the feature the webpart gets removed(deleted) from the gallery. I have written the code for removing the webpart from the gallery in the FeatureDeactivated event.

    Now on activating the feature i want the webpart to be populated into the gallery. can you please suggest me how to do it programmatically onthe FeatureActivated event ?????

    with regards
    Biju

  10. October 9, 2009 at 5:59 pm

    I learned a lot from reading this blog post. This site was very helpful to me on learning about some of the tips and stratedgys used in Webpart design.

  11. October 14, 2009 at 8:24 pm

    I don’t think you should be disposing of the SPSite object from a feature receiver.. Could be wrong, but I was under the impression that that reference was to the object owning the feature receiver, so you shouldn’t dispose of any objects returned by properties.Feature.Parent

  12. Hamed
    December 9, 2009 at 12:12 pm

    hi every body
    i’m having some strange problem!!
    i have nothing in my webpart gallery even the webparts built by system account,i dont know how to get back my list in gallery??
    every help would be appreciated

  13. RobertGraauw
    February 1, 2010 at 4:01 pm

    @Hamed
    To get all your webparts back simply click the ‘new’ menu in the web part gallery and then select the webparts you want in the next page by clicking the checkboxes and then click the Populate gallery button.

    But I guess, looking at the date, you might have figured this out by now

  1. March 22, 2009 at 12:38 pm
  2. March 23, 2009 at 12:12 am
  3. April 14, 2009 at 11:13 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: