by Andreas

Sharepoint 2010 – programmatically import and use web parts from site gallery

I recently discovered that when I export webparts with custom settings (like a CQWP with styling, filter values etc) and stored them in the site collection gallery, the configuration values were lost when programmatically importing them in a Visual Studio 2010 solution. The .webpart file created upon export contains all the custom settings, but this was ignored when using the standard add method ( SPLimitedWebPartManager.AddWebPart(…) ). All I got was a standard clean out-of-the box instance of the CQWP, which meant manual configuration was required.

To overcome this limitation there is another available method in the SPLimitedWebPartManager class: SPLimitedWebPartManager.ImportWebPart(…). This method takes an XmlReader parameter, which should get its data feed from the .webpart file stored in the gallery. The trick is to find the path to this file, but when you’ve got that it is simple to import it to your current page and then add it a web part zone. Here’s a snippet to help you get started:

    using (SPSite site = new SPSite(SPContext.Current.Site.Url))
    {
        SPList list = site.RootWeb.Lists["Web Part Gallery"];

        for (int i = 0; i < list.ItemCount; i++)
        {
            if (list.Items[i].Title.Contains("The title of my custom webpart"))
            {

... // you can figure out the rest

The following code is in the context of a newly created sub site, and I access the SPLimitedWebPartManager for a publishing page like this:

using (SPSite site = new SPSite(SPContext.Current.Site.Url))
    {
        // get reference to newly created sub site
        using (SPWeb web = site.AllWebs[_NewSiteGuid])
        {

            PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);

            PublishingPage page = pWeb.GetPublishingPage(_NewSiteUri);
            // check out page before making changes
            page.CheckOut();

            // access webparts
            SPLimitedWebPartManager wpMgr = web.GetLimitedWebPartManager(page.Uri.ToString(), PersonalizationScope.Shared);

...

A bit further down the actual import and adding occurs:

...

    string error = ""; // holds the potential error message
    // bit of ugly coding here, Robert C. Martin will shoot you if you use this!
    string exportedWebPartXml = new StringReader(site.RootWeb.GetFileAsString(site.RootWeb.Url + "/_catalogs/wp/SomeCustomFancyComponent.webpart")).ReadToEnd();
    // alter contents
    exportedWebPartXml = exportedWebPartXml.Replace("SomeValueThatShouldBeGeneric", "ThisOtherValueThatIsPageDependant");

    // create a reader
    XmlTextReader reader = new XmlTextReader(new StringReader(exportedWebPartXml));

    // wpMgr is an instance of SPLimitedWebPartManager
    System.Web.UI.WebControls.WebParts.WebPart importedWp = wpMgr.ImportWebPart(reader, out error);

    // make some other alterations if applicable
    importedWp.Title = "New title";

    // add the web part to the publishing page
    wpMgr.AddWebPart(importedWp, "TopBarLeftZone", 0);

...

Note: I have removed validation for increased readability, but before someone gets on my back for possible null pointer exception traps I just wanted to say it was deliberate!

If you expect to get anything out of this post, I assume you already know enough basic coding to see what’s going on. Basically, using the path pointing to the .webpart file the contents are read into the XmlTextReader and passed on to the ImportWebPart() method. The return parameter is an instance of your webpart (if you got the path correct…) which can then be added to a web part zone on your page.

Your custom settings are now preserved, and as you see in this code I also do some runtime alterations of the .webpart file contents which practically removes any boundries to what you can do.