How to overwrite SharePoint master page using a feature

I ran into a scenario where I had to overwrite an already existing master page using a feature.

In my elements.xml I had an entry for the custom master page like the following

   
   1: <Module Name="OSGMasterPages" Url="_catalogs/masterpage"   Path="MasterPages" RootWebOnly="TRUE">

   2: <File Url="default.master"   Type="GhostableInLibrary" >


I was unable to overwrite then found that the file has an additional attribute to specify what to do if the file already exists.

   
   1: <File   IgnoreIfAlreadyExists = "TRUE" | "FALSE"   

   2:    Name = "Text"   

   3:    NavBarHome = "TRUE" | "FALSE"  

   4:    Path = "Text"   

   5:    Type = "Text"   

   6:    Url = "Text >   

   7: </File>

IgnoreIfAlreadyExists – Optional Boolean. TRUE to provision the view even if the file aready exists at the specified URL; otherwise, FALSE.

I tried both TRUE and FALSE..no luck.

To add more twist to the problem I also got an error

error CS0030: Cannot convert type Microsoft.SharePoint.WebControls.EncodedLiteral’ to ‘System.Web.UI.IAttributeAccessor’

I tried to manually do the master page upload and then changed the site collection master page reference, it worked without any problem. Then I hit google found this site.

Investigated the custom master page and found lot of “_designer” variables which have been added through the SPD. If I remove this variables then the master page applied successfully and the site is alive.

Since this master page was also edited using the SPD i eagerly opened the page and checked..no luck… all the “designer “ variables looks like already commented out.

Note: Got a feedback from an anonymous user that if you go ahead and remove those variables the solution will work ! I am yet to try that

Thanks to the MSDN forums, Later I found that there is no way you can overwrite an existing file that is already provisioned by a feature. It has to be done programmatically !  and btw the IgnoreIfAlreadyExists attribute just lets the feature not error out if it hits that module and the file exists.

Feature event receiver is the right place to manage your provisioning of the updated master page. Following are the steps:

  • Find out if the master page that you want to replace is already checked out.
  • If yes then do a check in.
  • From the feature folder structure query for the master page file.
  • Add this file to the site collection master page gallery
  • Check in the file.
  • publish and approve the file.

The following is the sample code that does the same. This piece of code should be part of the Feature Activated Handler. You can modify the code so that you have the master page name parameterized.

       1: // Here we are trying to overwrite the default.master   

       2: oFile = oCurrentWeb.GetFile("_catalogs/masterpage/default.master");   

       3: oFolder = oCurrentWeb.Lists["Master Page Gallery"].RootFolder;   

       4: // Check In the file   

       5: if (oFile.CheckOutStatus != SPFile.SPCheckOutStatus.None)   

       6: oFile.CheckIn("auto checkin");   

       7: // Check Out the file for edit.   

       8: oFile.CheckOut();   

       9: string directory = oFeature.Definition.RootDirectory;  

      10: directory += @"\masterpages";  

      11: // Get the master page name from the feature properties as defined in the elements.xml  

      12: SPFeatureProperty oPropertyName = properties.Feature.Properties["MasterPageName"]; 

      13:  

      14: // Get the file names from the specified directory matching the feature property value.  

      15: string[] templates = Directory.GetFiles(directory, oPropertyName.Value, System.IO.SearchOption.TopDirectoryOnly);  

      16: // templates should have all the matching file names. In this instance it whould be only one file name.  

      17: string MasterPageFile = templates[0];  

      18: FileInfo fileInfo = new FileInfo(MasterPageFile);  

      19: byte[] byteArr = System.IO.File.ReadAllBytes(MasterPageFile);  

      20: oFolder.Files.Add(fileInfo.Name, byteArr, true);  

      21: oFile.Update();  

      22: oFile.CheckIn("Check in");  

      23: oFile.Publish("Published");  

      24: oFile.Approve("Approved");

If your site collections is referencing this master page then on feature activation the master page gets updated and it gets reflected on the site collection sites which uses this master page.

Advertisements

3 Responses

  1. I tried to provision a master page that is based on the blueband master page. I added my CSS files in the style folder within en-us folder and added my images in the images folder within the en-us folder. I provisioned everything and everything is working ok on my test machine. When i tried to activate the feature on the production server, it was activated successfully and then when I tried to open the website after activation, it gave me the 403 Forbidden error. I deactivated the feature and then I was able to use the master page without any problems. But after doing an iisreset, i lost all the images from the masterpage. Do you have any clue for what is going on?
    Thanks for advance

  2. Make sure that master page is published and not checked out.

  3. its really great work. I am getting error line no 12 and i fixed it in my post
    http://suryapulipati.blogspot.com/2012/07/sharepoint-master-page-is-not-updating.html.
    Thanks again for your post.

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

%d bloggers like this: