Programmatically removing all WebParts from a page in MOSS 2007


So I haven’t been around blogging for a while due to having a little downtime and finishing up a project I’ve been working on. I’ve just started a new project which involves migrating a very large SPS 2003 implementation to MOSS 2007.

Hopefully I’ll be back blogging regularly with some useful SharePoint related articles and to start off with I’m going to demonstrate how to delete all WebParts from a WebPart page programmatically.

This requirement came up recently as I needed to create a feature to delete all WebParts from the standard MySite template and add some custom WebParts when every MySite was provisioned.

The steps to accomplish this were as follows:

  1. Create a feature that when activated deleted all WebParts from the page and added my custom ones on.
  2. Create a feature stapler to staple my new feature to the SPSPERS template so the feature is activated each time a new MySite was provisioned.

I’m only going to cover step 1 here as there are plenty of great articles out there that explain feature stapling e.g. http://blogs.msdn.com/cjohnson/archive/2006/11/01/feature-stapling-in-wss-v3.aspx

Ok first we need to create a class that inherits from the SPFeatureReceiver class like so:

public class CustomMySiteWebPartsFeature : SPFeatureReceiver

The SPFeatureReceiver class is an abstract class with the following four abstract methods:

  • FeatureActivated(SPFeatureReceiverProperties properties)
  • FeatureDeactivating(SPFeatureReceiverProperties properties)
  • FeatureInstalled(SPFeatureReceiverProperties properties)
  • FeatureUninstalling(SPFeatureReceiverProperties properties)

We need to override all four of these methods but we only need to write our code in the FeatureActivated method so leave the others blank.

The first thing we do is get an instance of the SPWeb class which we can do by using the properties variable that is passed to the method.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

    using
(SPWeb web = properties.Feature.Parent as SPWeb)

    {
    }

}

Next we need to check that this is definately a MySite page we are working on just in case the feature gets activated on another site. We can do this by checking the WebTempate property of our SPWeb instance.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

    using
(SPWeb web = properties.Feature.Parent as SPWeb)

    {

        if
(web.WebTemplate == “SPSPERS” || web.WebTemplate == “SPSMSITEHOST”)

        {
       

    
}
}

To actually manipulate WebParts on our page we need to get an instance of the SPLimitedWebPartManager
class like this:

SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(“default.aspx”,
    PersonalizationScope.Shared);

And as you can see we call the GetLimitedWebPartManager method of our SPWeb instance for the page we want to manipulate.

Now we can begin to delete the WebParts. Below is the code I used to accomplish this.

List<Microsoft.SharePoint.WebPartPages.WebPart> webParts = new
List<Microsoft.SharePoint.WebPartPages.WebPart>();

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in manager.WebParts)
{
    webParts.Add(webPart);
}

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in webParts)
{
    manager.DeleteWebPart(webPart);
}

I first add all the WebParts to a collection then interate over that collection calling the DeleteWebPart method of our SPLimitedWebPartManager instance. We need to do this because calling DeleteWebPage while interating over the WebParts collection causes an exception as the collection has been altered during the enumeration.

When this is done we can use the AddWebPart method of the SPLimitedWebPartManager passing it an instance of the WebPart you want to add, the WebPartZone id you want to add the WebPart to and the index at which you want to add the WebPart within the zone.

After all this is done don’t forget to dispose the SPLimitedWebPartManager instance and call Update on the SPWeb instance:

manager.Dispose();
web.Update();

And that’s all there is to it.

Hope it was helpful.

16 thoughts on “Programmatically removing all WebParts from a page in MOSS 2007

  1. First of all thank you for your article. It helped me to understand how was this suppose to be done. But I do have a question.
    I have tried your solution and I get this error when I want to create a My site for a new user.

    There has been an error creating the personal site. Contact your site administrator for more information.

    Somethimes I get even Access Denied (request access or sign in as another user) error.
    Do you have any ideas on how to solve this?
    Thank you!

  2. Glad the article helped Peter.

    As for your error, it indicates to me that the code in the featureactivated method is falling over when the feature gets activated

    The best way to find out what’s happening is to deactivate the stapler feature at farm level and recreate the MySite so you get a standard MySite page. Then you can attach the Visual Studio debugger to your worker process and manually activate the feature so that execution drops into Visual Studio and you can step through to see whats falling over.

    Hope that helps.

  3. How do you customize new sites using Feature stapling?

    I mean I need to delete Out-Of-The-Box webparts and add custom webparts to new sites using feature stapling.

    I have 2 features: One feature staples the second feature to the STS#0 template and the second feature has the code to add\remove webparts programmatically and its code looks like

    SPWeb web = (SPWeb)properties.Feature.Parent;

    SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(“default.aspx”, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    SPLimitedWebPartCollection coll = manager.WebParts;

    But the problem is I can’t get SPLimitedWebPartManager object since I get error during debugging saying that the new site doesn’t exist. This means that I can’t add\remove webparts\lists from new site. Is this because FeatureActivated event is fired before the site gets created???

    Any workaround for this? Or how do I add\remove webparts\lists from new site during creation using feature stapling??

  4. That´s a great article but I´m still stuck with a problem.

    I need to deactivate a feature and them remove a specific WebPart from the WebPart Gallery (this is easy). I also need to remove this web part from all the pages using this control in all the WebPart Pages under a specific Site Collection.

    Any suggestions?

    Fábio

  5. I used 2 features to modify Mysite template,and i used your code to delete web parts.but My feature is activated before default.aspx buils so web part arent deleted.what can i do?

  6. Hello,

    Nice article.

    I actually did the same thing you did here but found an issue with this approach. Actually, I had to do some more things when MySite is created but one of the things I had to do was to remove most of the web parts from My Site public and private pages and to add some custom built web parts to those two pages (default.aspx and person.aspx).
    In order to get access to default.aspx page I had to mention it in ElementManifest.xml for my staplee feature. The section that I added to that XML is:

    That means that default.aspx will be available when FeatureActivated gets called. But the thing is, as “mit” mentioned, that default.aspx will not be fully constructed when FeatureActivated gets called and there will be no web parts in SPLimitedWebPartManager.WebParts collection.

    When I found out that there are no web parts in WebParts collection I started searching for solution on the net and found you blog post. I wonder if anyone was able to solve/figure out the problem?

    Kind regards,
    Sasa Popovic

  7. Hello,

    I was not able to find a solution for this problem so I made a workaround.
    I created a new web part (“Arranger”) that deletes not wanted web parts from the default.aspx page and I added that web part to the default.aspx page using the stapler & staple mechanism. Thefore, when MySite is created it will contain all default web parts and also my “Arranger” web part. When default.aspx page is accessed for the first time, the “Arranger” web part will delete all not wanted web parts and will delete itself at the end.

    If anyone else has a better idea or knows how to make this the right way, please share that with us.

    Regards,
    Sasa

  8. If you set the PersonalizationScope.User, will it delete all the Personalized Web Parts for all users, or just for the current user?
    I haven’t checked this,

    Regards,
    Darko

  9. Hi,

    as this approach is not working (the file default.aspx is not available when the stapling feature is activated), you should state that in the article. Otherwise it is misleading for people reading it.

    • The problem is that the site has not been fully provisioned at the time the featureactivated event is fired. The best way to do this is to add a delegate control to the master page used by the site. The delegate control will then run when the site is first visited. Do all your provisioning in the delegate code, i.e., remove/add webparts and finally deactivate the delegate feature. In this way the delegate control only runs once.

  10. Hi

    Can you please tell how to Programmatically populate the WebParts into the gallery, which was previously deleted from the “Webpart Gallery” list ?

    With regards
    Biju

  11. Hello,
    Very nice post, very helpful. Just something I would like to know on top of this.

    I would like to make webparts(some of them) unavailable upon feature activation and back available when feature is deactivated. I can remove them with help of above solution but how to get them back?

    Thanks in advance

  12. Pingback: How to delete Web Part instances on pages using Feautures – FeatureReceiver – SPLimitedWebPartManager | SharePointDevWiki.com

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