SharePoint.BG

A fine bunch of Bulgarian SharePoint bloggers sharing experiences....

The use of RaisePostBackEvent in SharePoint Publishing Layout Pages

Why we should ever override RaisePostBackEvent in a SharePoint Publishing Layout Page?

We sometimes run into situations where your program needs to perform SharePoint list item updates depending on the changes made by the user to fields of that publishing page.

A simple example - let's say that you need to do server-side validation on a field, or you need to set a value of a list item column or do something before the page gets persisted through the SharePoint data access later. In our case, we had to fire code before the save event occurs on the current time and we had to add some data in other (hidden) fields, which we read later.

In simple words, this blog post is a walkthrough about capturing the RaisePostBackEvent code-behind method on publishing pages and performing actions before the save event occurs.

For this purpose I have prepared a simple example in a bundled ZIP file. I will try to describe how the SharePoint publishing page list item can be programmatically updated by using the RaisePostBackEvent when the save page event occurs.

 

I have split my example into two phases. The first phase explains how to create a simple (custom) publishing page layout so if you are familiar with this you can skip it and continue with the second phase where the RaisePosBackEvent comes into play.

I am using SharePoint Server 2010 with Visual Studio 2012 installed on the server.

Phase 1. Creating a SharePoint solution and custom page layout.

  1. Open the Visual Studio and create SharePoint 2010 Empty Project
  2. Specify the site on your local SharePoint server that you want to use for debugging. I am using a Publishing Site (Out of the box).
  3. Once the project is created add an empty module that will be used to hold our custom page layout.
  4. Rename the module and the feature so the project looks better, I have renamed mine:image
  5. Now for the creation of our custom page layout I will use one of the existing ones under my Publishing Site -> Site Settings -> Master Pages and Page Layouts.
  6. You can navigate to there and download one of the existing. I downloaded ArticleLeft.aspx. (/_catalogs/masterpage)
  7. After the page layout is downloaded you can add it to your MyPageLayouts module and rename it to MyCustomLayout.aspx for example. We are doing this to reuse the ASPX of the page layout and not have to create our own.
  8. Delete the Sample.txt from the module since it is not needed. VS puts that crap in there.
  9. Update the Elements.xml so it would look like:
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <Module Name="MyPageLayouts" Url="_catalogs/masterpage" >
   4:   <File Path="MyPageLayouts\MyCustomLayout.aspx" 
   5:     Url="MyPageLayouts/MyCustomLayout.aspx" 
   6:     Type="GhostableInLibrary" />
   7: </Module>
   8: </Elements>

10. Add the MyPageLayouts module to the MyCustomFeature

image

11. Run/Start the solution to verify that the newly created MycustomLayout.apsx works as expected.

12. Go to the Publishing Site and edit the dafault.aspx, in the Ribbon go on the Page Layout button and verify that the MyCustomLayout.aspx is there.

image 

14. Change the page layout to our custom so we can use it in the next phase or create one new publishing page in the "Pages" Document Library and apply the custom layout.

Phase 2. Using the RaisePostBakcEvent method to programmatically update list item field in the "Pages" Document Library when publishing page save event occurs

If you are not familiar with the Page.RaisePostBackEvent, one very good article with nice illustration can be found on this link: http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx.

As part of the ASP.NET Page Life Cycle the RaisePostBackEvent is called in the PublishingLayoutPage (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishinglayoutpage.aspx) as well.

 

Back to the solution:

  1. Create a new empty Class.cs and name it PublishingLayoutEx.cs
  2. The new class will inherit the PublishingLayoutPage and for that reason references to Microsoft.SharePoint and Microsoft.SharePoint.Publishing should be added to the project.
  3. Also references (using) to Microsoft.SharePoint and Microsoft.SharePoint.Publishing should be added in the newly created class as well.
  4. Also reference to System.Web needs to be added to the solution because the RaisePostBackEvent method resides in System.Web.UI.Page(http://msdn.microsoft.com/EN-US/library/dfbt9et1) and the compiler would not recognize it if System.Web is not referenced.
  5. The complete references on the image below:

image

 

 

Your PublishingLayoutPageEx class should look like:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using Microsoft.SharePoint;
   6: using Microsoft.SharePoint.Publishing;
   7:  
   8:  
   9: namespace MyProject
  10: {
  11:     public class PublishingLayoutPageEx : PublishingLayoutPage
  12:     {
  13:     }
  14: }

 

6. Go to your page layout "MyCustomPageLayout.aspx" and replace the page directive

 

   1: REPLACE:
   2: <%@ Page language="C#"
   3: Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
   4:  
   5: WITH:
   6: <%@ Page language="C#" 
   7: Inherits="MyProject.PublishingLayoutPageEx,$SharePoint.Project.AssemblyFullName$" %>
   8:  

...so the publishing page inherits your newly created class.

7. Add the RaisePostBackEvent to the class:

   1: namespace MyProject
   2: {
   3:     public class PublishingLayoutPageEx : PublishingLayoutPage
   4:     {
   5:         protected override void RaisePostBackEvent(System.Web.UI.IPostBackEventHandler sourceControl, string eventArgument)
   6:         {
   7:             base.RaisePostBackEvent(sourceControl, eventArgument);
   8:         }
   9:     }
  10: }

8. Now we can start to listen for eventArguments raised by different events (to be exact, the method is overridden).

9. Start the solution, go to the site and change the default.aspx page layout to match our custom MyCustomLayout.aspx or just create a new publishing page and apply the layout.

10. Use the edit button on the page to enter in edit mode.

clip_image001[6]

If you have the debugger on, you can observe the eventArgument of the RaisePostBackEvent. It is "edit"

clip_image002

11. Another experiment would be to hit the SaveAndClose button and observe the eventArgument

clip_image001[8]

clip_image002[5]

12. And you can play around with other ribbon buttons like CheckIn, Publish etc, but that is the pay to capture them.

13. Now, new functionality can be easily added when save event is risen.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using Microsoft.SharePoint;
   6: using Microsoft.SharePoint.Publishing;
   7:  
   8: namespace MyProject
   9: {
  10:     public class PublishingLayoutPageEx : PublishingLayoutPage
  11:     {
  12:         protected override void RaisePostBackEvent(System.Web.UI.IPostBackEventHandler sourceControl, string eventArgument)
  13:         {
  14:             if (eventArgument == "PageStateGroupSaveAndStop")
  15:             {
  16:                 var item = SPContext.Current.ListItem;
  17:                 item["Comments"] = String.Format("Last saved at {0}", DateTime.Now); //you can use a better way to set field values
  18:             }
  19:  
  20:             base.RaisePostBackEvent(sourceControl, eventArgument);
  21:         }
  22:     }
  23: }

This is pretty much all of it: placing code for adding DateTime.Now in the "Comments" field if the eventArgument is "PageStateGroupSaveAndStop". We do this before the RaisePostBackEvent then the normal save handler should update the list item with the changes made by the user. Notice we do not call the Update method on the list item, that is done internally by SharePoint

Useful links

Here are some useful links with PageStateCommands and PageStateStrings that can be risen as eventArgument in the RaisePostBackEvent method.

SP.Ribbon.PageState.PageStateCommands Fields:

http://msdn.microsoft.com/en-us/library/ee551465(v=office.14).aspx

SP.Ribbon.PageState.PageStateStrings Fields:

http://msdn.microsoft.com/en-us/library/ee556269(v=office.14).aspx

I have not tested all of them, some may not be appropriate.

Bare in mind these are not all of the page states of the Ribbon that can be passed as eventArgumens in the RaisePostBackEvent method. I have discovered a few others during my development that are not listed in MSDN (like ChangePageLayoutEvent, PageStateGroupSaveSplit, PageStateGroupOpenMenuSave, PageStateGroupQuerySaveMenu) and maybe there are more.

 

Velin Georgiev is a Front-End Developer at OneBit Software, focused on developing end-to-end SharePoint, ASP.NET MVC and Cloud-based solutions. With more than 5 years of web development experience, Velin is a key talent in building user interfaces which integrate with SharePoint. Velin strong interest in JavaScript libraries, the efficient and appropriate use of cascading style sheets, MVC and other scripting web platforms makes him a valuable asset in any project involving front-end capabilities. Velin holds more than 15 certificates of which 4 are at the MCPD level. @VelinGeorgiev

Comments (1) -

Pingbacks and trackbacks (1)+

Add comment

Loading