Add web parts from the gallery in SharePoint by code

For some reason I have never until now needed to add web parts to a page from the gallery using code. Why would I ever do this? The code runs inside a Feature Receiver, and is executed when creating new sites. The web part had been extended from a standard Content by Query Web Part (CBWP) with no code, and for that reason it was not possible to reference a unique class. So for this rare case I ended up with creating a utility function I thought was nice to share.

Function to add web parts from gallery

[code language="csharp"]

private static WebPart AddWebPartFromGallery(SPWeb web, SPLimitedWebPartManager wpm, string webPartFilename)
{
string errorMessage;

var query = new SPQuery
{
Query = String.Format(CultureInfo.CurrentCulture,
"<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='File'>{0}</Value></Eq></Where>",
webPartFilename)
};

var webPartGallery = web.IsRootWeb ? web.GetCatalog(SPListTemplateType.WebPartCatalog) : web.Site.RootWeb.GetCatalog(SPListTemplateType.WebPartCatalog);
var webParts = webPartGallery.GetItems(query);
XmlReader xmlReader = new XmlTextReader(webParts[0].File.OpenBinaryStream());
var webPart = (WebPart) wpm.ImportWebPart(xmlReader, out errorMessage);

if (!string.IsNullOrEmpty(errorMessage))
throw new ApplicationException("Error importing Web Part (" + webPartFilename + "): " + errorMessage);

return webPart;
}

[/code]

How to use the function

This example code shows how to retreive the web part manager, checkout the file, add the web part and finally publish it again.

[code language="csharp"]

// Get web and its web part manager
var web = new SPWeb("http://intranet.contoso.com");
var pagesLibraryName = SPUtility.GetLocalizedString("$Resources:List_Pages_UrlName", "cmscore", web.Language);
var file = web.GetFile(web.Url + "/" + pagesLibraryName + "/" + "default.aspx");
file.CheckOut();
var wpm = web.GetLimitedWebPartManager(web.Url + "/" + pagesLibraryName + "/" + "default.aspx", PersonalizationScope.Shared);

// Get the web part from the sites gallery
var customWebPart = AddWebPartFromGallery(web, wpm, "CustomWebPart.webpart");

// Add the web part to the page and publish the page
wpm.AddWebPart(customWebPart, MyZoneId, 1);
wpm.SaveChanges(customWebPart);
file.CheckIn("Checked in by feature");
file.Publish("Published by feature");

[/code]

Summary

Retrieving and adding web parts from the web part gallery by code is more complex than utilizing web parts you can access by their class. This post shows you how to retrieve the web part from the gallery and add it to a web part zone within a standard publishing page.