SharePoint 2010: Updating MasterPages and Page Layouts – using Feature

I was facing issue while trying to deploying the custom Page layout. Below feature code giving issue while activation,

<Module Name="MasterPageModule" Url ="_catalogs/masterpage" List="116">
 <File Path="MasterPageModule\defaultTemplate.aspx" Url="defaultTemplate.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">
  <Property Name="Title" Value="My Custom Page Layout" />
  <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
  <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
  <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/ArticleLinks.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/ArticleLinks.png" />
  <Property Name="PublishingAssociatedContentType" Value=";#Welcome Page;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D4;#" />
 </File>

Problem statement : This give below issue,

Error occurred in deployment step ‘Activate Features’: A file specified in the modules section of this template already exists.

When I set IgnoreIfAlreadyExists=”TRUE” layout is not updated. And also I can’t delete this layout by Sharepoint Designer because “This item cannot be delete because it is still referenced by other pages”. Yes, it’s definitely referenced by some pages but in development i need to update it many times.

Solution to given Problem:

IgnoreIfAlreadyExists attribute within Module element can be tricky because sometimes it doesn’t work to update the MasterPages and Page Layouts properly. The following code can be helpful in performing updates upon Feature Activation.
 using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using System.Xml;
using System.Collections;
using System.Linq;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint.Security;
namespace TestSPSolution
{
     public class UpdatePagesFeatureReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
if (properties != null)
{
using (SPSite currentSite = (SPSite)properties.Feature.Parent)
{
using (var web = currentSite.OpenWeb())
{
var ElementDefinitions = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);                        foreach (SPElementDefinition ElementDefinition in ElementDefinitions)
{
if (ElementDefinition.ElementType == “Module”)
{
Helper.UpdateFilesInModule(ElementDefinition, web);
}
}
}}
}
}public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//// throw new NotImplementedException();
}

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
////throw new NotImplementedException();
}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
//// throw new NotImplementedException();
}
}

internal static class Helper
{
internal static void UpdateFilesInModule(SPElementDefinition elementDefinition, SPWeb web)
{
XElement xml = elementDefinition.XmlDefinition.ToXElement();
XNamespace xmlns = “http://schemas.microsoft.com/sharepoint/&#8221;;
string featureDir = elementDefinition.FeatureDefinition.RootDirectory;
Module module = (from m in xml.DescendantsAndSelf()
select new Module
{
ProvisioningUrl = m.Attribute(“Url”).Value,
PhysicalPath = featureDir,
Files = (from f in m.Elements(xmlns.GetName(“File”))
select new Module.File
{

FilePath = (m.Attribute(“Path”) == null) ? string.Empty : Path.Combine(featureDir, m.Attribute(“Path”).Value),
Name = f.Attribute(“Url”).Value,
Properties = (from p in f.Elements(xmlns.GetName(“Property”))
select p).ToDictionary(
n => n.Attribute(“Name”).Value,
v => v.Attribute(“Value”).Value)
}).ToArray()
}).First();

if (module == null)
{
return;
}

foreach (Module.File file in module.Files)
{

string physicalPath = string.IsNullOrEmpty(file.FilePath) ? Path.Combine(module.PhysicalPath, file.Name) : Path.Combine(file.FilePath, file.Name);
string virtualPath = string.Concat(web.Url, “/”, module.ProvisioningUrl, “/”, file.Name);

if (File.Exists(physicalPath))
{
using (StreamReader sreader = new StreamReader(physicalPath))
{
if (!CheckOutStatus(web.GetFile(virtualPath)))
{
web.GetFile(virtualPath).CheckOut();
}
SPFile spFile = web.Files.Add(virtualPath, sreader.BaseStream, new Hashtable(file.Properties), true);
spFile.CheckIn(“Updated”, SPCheckinType.MajorCheckIn);
if (CheckContentApproval(spFile.Item))
{
spFile.Approve(“Updated”);
}

spFile.Update();
}
}
}

}

private static bool CheckOutStatus(SPFile file)
{
if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
{
return true;
}
else
{
return false;
}
}

private static bool CheckContentApproval(SPListItem listitem)
{
bool isContentApprovalEnabled = listitem.ParentList.EnableModeration;

return isContentApprovalEnabled;
}

public static XElement ToXElement(this XmlNode node)
{
XDocument xDoc = new XDocument();

using (XmlWriter xmlWriter = xDoc.CreateWriter())

node.WriteTo(xmlWriter);

return xDoc.Root;

}
}

public class Module
{
public string ProvisioningUrl { get; set; }
public string PhysicalPath { get; set; }
public Module.File[] Files { get; set; }

public class File
{
public string FilePath { get; set; }
public string Name { get; set; }
public Dictionary Properties { get; set; }
}
}
}

Advertisements

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