4

I am provisioning a publishing page as part of a feature and placing a single list view web part on the page (see code below). This all works perfectly sp far.

<Elements>
    <Module>
        <File Path="default.aspx" Url="BulletinBoard.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE">
            <Property Name="Title" Value="Bulletin Board" />
            <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/ListNewsletterStyle.aspx" />
            <Property Name="ContentType" Value="Page" />
            <Property Name="PublishingPageImage" Value="" />
            <View List="Lists/BulletinBoard" BaseViewID="2" WebPartZoneID="Main" WebPartOrder="1">
                <![CDATA[
                <webParts>
                    <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
                        <metaData>
                            <type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" />
                            <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
                        </metaData>
                        <data>
                            <properties>
                                <property name="Title">Active Announcements</property>
                                <property name="ChromeType">None</property>
                            </properties>
                        </data>
                    </webPart>
                </webParts>
                ]]>
            </View>
        </File>
    </Module>
</Elements>

The only problem is that each time I redeploy my feature through Visual Studio, the list view web part is duplicated (i.e. another one is added to the web part zone).

This problem only appears to affect web parts with the <View ...> tag. Web parts provisioned with the <AllUsersWebPart ...> tag are not being duplicated.

How do I prevent this?

3 Answers3

2

You can add a feature receiver and add the webpart if it not alreay exists in stead of adding the webpart in XML. What do you mean by tag?

Anita Boerboom
  • 586
  • 3
  • 4
  • Thank-you for your recommendation Anita. Admittedly, for consistency-sake, I was hoping to provision all my pages and web parts in the same place (via the feature XML), but I could definitely use the feature receiver to check for any duplicates and remove them where necessary. As for the "tag" reference, StackOverFlow didn't include my HTML markup in my post, please see the updates above. –  Apr 14 '11 at 08:39
1

Check out this blog entry from Waldek Mastykarz. It has the C# code below that should be similar to what you are looking for.

using (SPSite site = new SPSite("http://sharepoint"))
{
  SPList list = site.GetCatalog(SPListTemplateType.MasterPageCatalog);
  SPListItemCollection items = list.Items;
  List<string> webParts = new List<string>();

  // find the right Page Layout
  foreach (SPListItem item in items)
  {
    if (item.Name.Equals("CustomPageLayout.aspx",
      StringComparison.CurrentCultureIgnoreCase))
    {
      SPFile file = item.File;
      // get the Web Part Manager for the Page Layout
      SPLimitedWebPartManager wpm =
        file.GetLimitedWebPartManager(PersonalizationScope.Shared);
      // iterate through all Web Parts and remove duplicates
      while (wpm.WebParts.Count > 0)
      {
        StringBuilder sb = new StringBuilder();
        XmlWriterSettings xws = new XmlWriterSettings();
        xws.OmitXmlDeclaration = true;
        XmlWriter xw = XmlWriter.Create(sb, xws);
        System.Web.UI.WebControls.WebParts.WebPart wp =
          wpm.WebParts[0];
        wpm.ExportWebPart(wp, xw);
        xw.Flush();
        string md5Hash = getMd5Hash(sb.ToString());
        if (webParts.Contains(md5Hash))
          wpm.DeleteWebPart(wp);
        else
          webParts.Add(md5Hash);
      }
    }
  }
}
skeletank
  • 2,880
  • 5
  • 43
  • 75
  • In my particular case, I used a feature receiver to delete the web parts that were provisoned by the feature upon deactivation. This "cleared the way" for the new web parts when the feature was reactivated (e.g. like when you redeploy from Visual Studio during development). I found some great Linq code for this which analysed the feature's manifest and removed all the web part instances that only it provisioned, so there were no hardcoded page layout names etc. And since my web parts weren't personalisable, there were no user's changes / settings that would be lost upon deleting the web parts. –  Feb 16 '12 at 02:48
  • Do you have a linke to the code for that? I run code similar to the one above in a feature receiver as well but your solution sounds more complete. – skeletank Feb 16 '12 at 14:04
  • [Update] This is the blog post that I used: http://platinumdogs.wordpress.com/2009/08/10/removing-provisioned-files-from-sharepoint-during-feature-deactivation/ –  Feb 20 '12 at 08:34
0

Note to SharePoint 2013 users. You should add ReplaceContent=True to the tag. The duplicate webpart issue will be resolved.