Automatically Check In Files in a SharePoint 2010 Sandbox Feature Event Receiver
This post is one post in a series of posts I penned in hopes it would help those looking to move a SharePoint 2010 Visual Studio 2010 farm based solution to a sandbox. There are many gotcha’s and pitfalls that you may run into or you may want to be aware of. You can learn more about this series here as well as download the CodePlex Project, From the Farm to the Sandbox, which includes the sample farm and sandbox solutions references through this series.
The related posts include:
Housekeeping on Deactivation – Removing What You Added
The Proper Web Part Control Class for a SharePoint 2010 Sandbox Solution
Custom Properties in a SharePoint 2010 Sandbox Web Part
Why CSSRegistration Will Not Work in a SharePoint 2010 Sandbox Solution
Why do we need to check in files?
In a farmed based solution, assets that are added to a SharePoint Site Collection or Web via a Module are normally checked in, published and approved, at least if they are set as Ghostable. You will find that this is not the case with assets added via a module in a sandbox solution, assuming that you have publishing enabled.
I do not have the specific reason for this but I suspect it has something to do with the fact the assets are not being added to the file system, rather they are added only to a list within your site collection. Also, in a sandbox, it may be better for a site collection admin to review what a sandbox added via a module and verify it.
A typical process of checking in files may include using the GetElementDefinitions(CultureInfo.CurrentCulture) function in your event receiver FeatureActivated function.
Microsoft.SharePoint.Administration.SPElementDefinitionCollection spFeatureElements = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);
Then you might loop through all of these elements looking for modules.
SPSite spSite = properties.Feature.Parent as SPSite;
List<String> lModuleFiles = new List<String>();
foreach (SPElementDefinition spElementDefinition in spFeatureElements)
if (spElementDefinition.ElementType == "Module")
XmlElement xmlElementNode = (XmlElement) spElementDefinition.XmlDefinition;
String sModUrl = SPUtility.ConcatUrls(spSite.Url, xmlElementNode.GetAttribute("Url"));
foreach (XmlElement xmlChildElementNode in xmlElementNode.ChildNodes)
if (xmlChildElementNode.Name == "File")
String sFile = SPUtility.ConcatUrls(sModUrl, xmlChildElementNode.GetAttribute("Url"));
Now that you have a list of module files in your List, lModuleFiles, loop though those and check them in. To see how to do this refer to the Farm solution’s Feature Event Receiver in From the Farm to the Sandbox at CodePlex. What is wrong with this code though in a sandbox? Well primarily, our first line here, Microsoft.SharePoint.Administration.SPElementDefinitionCollection spFeatureElements = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);
This requires the use of Microsoft.SharePoint.Administration.SPElementDefinitionCollection but low and behold, that is not available in Sandbox solutions.
Anyhow, what is the fix?
There is a great article, http://stefan-stanev-sharepoint-blog.blogspot.com/2011/01/automatically-publishing-files.html that walks through a great process of checking in and publishing all of the files in a module without using SPElementDefinitionCollection. The strategy is actually quite elegant, although it’s predicated on modifying your module’s elements.xml file to include a second Module block similar to:
<Module Name="Style Library Manifest">
<File Path="Style LibraryElements.xml" Url="ElementsSL_$SharePoint.Feature.Id$.xml" Type="Ghostable" />
What this does is tells SharePoint to also copy this Module’s Elements.xml file to the root of the scope of this feature, i.e. for a feature scoped to a site, the Elements.xml file will be copied to the root of the site collection. The Elements.xml file is then used during the activated step of the Feature’s Event Receiver to provide a list of all assets added by the Module. The code can then loop through the module’s assets and verify that they are checked in, publishing and approved. This actually works fine in a farm solution as well, but since we cannot get a hold of the elements.xml file in a sandbox solution via SPElementDefinitionCollection, we need to make our own copy of each module’s elements.xml file and work from there. Review the Sandbox solution Feature Event Receiver at From the Farm to the Sandbox for the full code.
If you have another solution to the problem of automatically publishing module files in a SharePoint 2010 Sandbox, please share them with us. Also, please do not forget to check out the other posts in this series, all related to converting a farm solution to a sandbox solution.