Sunday 22 September 2013

Working with BeforeProperties and AfterProperties on SPItemEventReceiver

I always forget this and when I come to create a new SharePoint Event Receiver I wonder why the BeforeProperties or AfterProperties are sometimes not populated.

Consider an example, we need to handle the ItemUpdating event for a document library and prevent a user from changing a certain column.  The code might look like this:
public override void ItemUpdating(SPItemEventProperties properties)
{
 if (properties.BeforeProperties["Title"] != properties.AfterProperties["Title"])
    {
        properties.Cancel = true;
        properties.ErrorMessage = "This column cannot be changed";
    }
}
For a document library, this works just fine.  For documents, Before and After properties are guaranteed for post events, such as ItemUpdating and ItemUpdated, but Before properties are not available for post events on list items.

The Before/After properties works differently between LIST and DOCUMENT LIBRARY

SharePointList

Event
BeforeProperties
AfterProperties
ListItem
ItemAdding
Null
New  Value
Null
ItemAdded
Null
New Value
New Value
ItemUpdating
Null
Changed Value
Original Value
ItemUpdated
Null
Changed Value
Changed Value
ItemDeleting
Null
Null
Original Value
ItemDeleted
Null
Null
Null

 
SharePointDocument Library
Event
BeforeProperties
AfterProperties
ListItem
ItemAdding
Null
Null
Null
ItemAdded
Null
Null
New Value
ItemUpdating
Original Value
Changed Value
Original Value
ItemUpdated
Original Value
Changed Value
Changed Value
ItemDeleting
Null
Null
Original Value
ItemDeleted
Null
Null
Null

Properties.ListItem refers to the current list item values at this point in the event. 
Original Value refers to the value which is already existing in the content DB.
New Value refers to the value which is being added newly in add event.
Changed Value refers to the value which is being updated in Update event.
So, if we go back to our original problem listed above.  How can we prevent a user from changing a certain column for an item in a list event?  From the list table, you can see if we hook into the ItemUpdating event, we can compare the current item’s value (properties.ListItem) to the AfterProperties value.  The code would look like this:
// SPListItem item= properties.ListItem;
// String oldvalue=item[“Title”].ToString();
if (properties.ListItem["Title"] != properties.AfterProperties["Title"])
{
    properties.Cancel = true;
    properties.ErrorMessage = "This column cannot be changed";
}
Hope it Helps.. 


Thursday 19 September 2013

correlation tokens in SharePoint workflow

Correlation Token:
  • Is way to group together a set of related activity.
  • worflowTokem - created by default in workflows used to group together the whole workflow.
  • Is a unique identifier that enables mapping between the objects in a workflow and the environment that is hosting the Windows Workflow Foundation (WF) workflow runtime.
  • It can be referred for uniquely identifying each instance of a workflow, modification or task.  When SharePoint initiates a workflow, it does not have a unique set of objects. Instead, if one instance of the workflow is already running when the second initiates, the second will reuse objects from the first.
  • Correlation token properties ensure that the single activity object is operating on the correct workflow instance and accessing the correct details about the workflow.

You will have a separate correlation token for the each of the following:

  • The workflow itself.
  • Each task you need to reference in the workflow

Declare the correlation token for the workflow in the OnWorkflowActivated activity. Then, for each activity that affects the entire workflow, bind that activity’s correlation token to the correlation token of the OnWorkflowActivated activity.

Tuesday 3 September 2013

Setting Workflow Status to Custom Values

If you consider workflow in SharePoint 2010,it will have certain default status such as In Progress,Completed,Failed on Start,Completed,etc..

but in case if we want custom values for the workflow that would enhance the look of the workflow status to the end user in more convenient way.

Steps Involved:

Note: I'm using Sequential Workflow,This can be used for state machine workflow also.
  1. Create a sequential workflow and select the type as List Workflow,
  2. So the Project explorer will look like,

    3. Edit the Element.xml file and add  the below custom tags just above the ending “Metadata” node,

    <ExtendedStatusColumnValues>
    <StatusColumnValue>Pending</StatusColumnValue>
    <StatusColumnValue>Approved</StatusColumnValue>
    <StatusColumnValue>Rejected</StatusColumnValue>
    </ExtendedStatusColumnValues>
    4. Let the logic in .cs file be as it is,now add a SetState activity form the toolbox and name it as setState1(any name you prefer) and this must be placed as the last activity in the workflow,then only it will work based on logic provided in all the other states located above.
    5.In the propeties of setstate activity give a name for MethodInvoking property,let it be "setState1_MethodInvoking"

    6. The integer value of the MAX is 15. From 0 to 14, the numbers are reserved for default values like InProgress, completed, error occurred etc. In Element.xml, the value of the first custom value will be 15 and then it will keep on increasing by 1. 
     So the values represented will be like,
    SPworkflowStatus.Max------>Pending
    SPworkflowStatus.Max+1------>Approved
    SPworkflowStatus.Max+2------>Rejected

    7. Build and Deploy to enjoy the result.



Wednesday 21 August 2013

Differences between Event Receivers and SharePoint Workflows




Event Receivers
Workflows
1.
Can be Executed Synchronously or Asynchronously.
Can be Executed only Asynchronously which means when an action is completed.

2.
Since it is executing in both modes we can cancel the action which is going to be occurred.
Once an action is started you cannot stop the operation.

3.
Can't be initiated manually
Can be initiated automatically or manually.

4.
Logs are not possible
Log can be written in workflows

5.
Can be used in actions that needs to be completed immediately based on logic (Immediate execution)
Can be used in actions that will take even months or years to complete.( Long running)

6.
no state is maintained
Workflow maintains state.

7.
Triggered on Synchronous or Asynchronous events.
Triggered only on Creation/Change/deletion events.

Event Receivers - SharePoint

An event receiver has a set of base classes that can contains one or more methods known as event handlers that are executed automatically by SharePoint in response to events such as adding or deleting item to a list/library. You can use event handlers for the different operations on different lists, document libraries and content types.

Types of Event Receivers:


  1. Synchronous - Events are executed before the action is executed on the content database.

         Events ending with -ing are named as Synchronous Event Receivers
         Ex. Item Deleting,Item Adding.
    2.  A Synchronous - Events are executed after the action is executed on the content database.

         Events ending with -ed are named as Synchronous Event Receivers
         Ex. Item Deleted,Item Added.

Different Base Classes in Event Receivers:

     There are totally 5 base classes in SharePoint 2010,
  1. SPItemEventReceiver - Event at List item Level.
  2. SPListEventReceiver - Event at List Level.
  3. SPFeatureEventReceiver - Event activation and Deactivation at list level.
    1. FeatureInstalled: Right after feature is installed.
    2. FeatureActivated: Right after feature activation through “Site Settings” or otherwise.
    3. FeatureDeactivated: Right after feature deactivation through “Site Settings” or otherwise.
    4. FeatureUninstalled: Before feature is uninstalled.
  4. SPEmailEventReceiver :Event to send mail to list
  5. SPWebEventReceiver : Event at Web Site Level.(Site added,site deleted,etc..)
Disabling and Enabling the event Receiver

If we are modifying/updating the same List item using event receiver,then the event receiver is triggered again and again.So you have to prevent it from firing before you update changes to the list item. We can implement this functionality using EnableEventFiring attribute to true/false.

Example:
   public override void ItemAdded(SPItemEventProperties properties)
    {
        //will disable the event receiver
        EventFiringEnabled = false;
        
        //do some action on list like update List.Update()
 
        //will enable the event receiver
        EventFiringEnabled = true;
    }

Best practice is to set Disable EventFiring method right before any update action and Enable EventFiring method right after updating action has been completed.






Tuesday 16 July 2013

Creating Page Layouts in SharePoint


A "Page Layout" is a page template that controls how the page looks and exactly which elements (such as lists and libraries) should be present on the page by default when the page has been created using these layouts.



By default SharePoint Provides so many inbuilt layouts like Splash, Blank web part under three content types Article, Redirect and Welcome Page.
We can either create Page Layout from the scratch or customize the copy that comes along with SharePoint.



“PlaceHolderMain” ContentPlaceHolder is the content area reflecting form MasterPage.
You can code all your items inside “PlaceHolderMain”.

Using its PageDisplayMode property, you can make one set of content viewable when the page is in ‘Display’ mode and another set viewable when the page is in ‘Edit’ mode.

When creating Page Layout you need to consider two areas mainly,

·         Display Mode (Page not being Edited)
In ‘Display’ meant the content was visible to anyone who could see the page (as long as the page was in ‘Display’ mode and wasn’t being edited).

FieldName : Refers to the Field name available in Content type

·         Edit Mode (Page being Edited)

In Edit mode, user can edit the content only when the page is edited and it will not visible to the user unless this particular field is coded in Display Section.
For this we have a separate section named Edit mode panel

Example Demonstrating Display and Edit Mode

<asp:Content ContentPlaceholderID="PlaceHolderMain" runat="server">
//Display Mode
<!-- Add field controls here to bind custom metadata viewable and editable in  edit and Published mode.-->
<div>
<SharePointWebControls:TextField FieldName="Title" runat="server"/>
</div>
//Edit Mode
                <PublishingWebControls:editmodepanel runat="server" id="editmodepanel1">
                                <!-- Add field controls here to bind custom metadata viewable and editable in                                   edit mode only.-->
                <SharePointWebControls:TextField FieldName="ArticleByLine" runat="server"/>

                <PublishingWebControls:RichHtmlField ID=”RichHtmlField2″       FieldName=”     PublishingPageContent″ runat=”server”/>

                <SharePointWebControls:datetimefield FieldName="ArticleStartDate" runat="server"                 id="datetimefield3"></SharePointWebControls:datetimefield>               
                </PublishingWebControls:editmodepanel>
 </asp:Content>

In Edit mode panel into your layout, you can place page fields, such as Title or Schedule Dates,   into this panel, allowing you and your editors to add or change this content while they're editing  the page rather than going to the page library to add this information.


In SharePoint 2010 behavior has been changed. Now the EditModePanel control will only shows its contents to users who have permissions to edit the page, regardless of the page’s display mode.
There is another control related to EditModePanel called the AuthoringContainer control. At first glance             it seems pretty similar to EditModePanel except for one key difference: theDisplayAudience property, which can be set to ReadersOnly or AuthorsOnly.


Sample Code that will be useful when creating the page layout in 2010 using SharePoint Designer,
<PublishingWebControls:AuthoringContainer DisplayAudience="ReadersOnly" runat="server">
    <!-- Content you want visible to uses without 'edit' permissions goes here. -->
</PublishingWebControls:AuthoringContainer>

<PublishingWebControls:AuthoringContainer DisplayAudience="AuthorsOnly" runat="server">
    <PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Display">
        <!-- Content you want visible to users with 'edit' permissions and in display mode goes here -->
    </PublishingWebControls:EditModePanel>

    <PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Edit">
        <!-- Content you want visible to users *with* 'edit' permissions and in edit mode goes here -->
    </PublishingWebControls:EditModePanel>
</PublishingWebControls:AuthoringContainer>


Monday 15 July 2013

Displaying Custom Fields in Content Query Web Part

The Content Query Web Part (CQWP) allows you to display data from a list anywhere within a Site Collection..


However, by default the CQWP only displays the freaking ‘Title’ field, if you want to display all the other field in the list you have to do all the below modifications,
                                              

In the Tool Pane, expand Presentation and experiment with the drop down options under Styles. Select Apply to see the changes. These are default styles available in MOSS 2007.
All these styles will be available in a single file named “ITEMSTYLE.XSL”. This file is available under Style Library/XSL Style Sheets/.You can use SharePoint designer to customize this file.

Take a minute to look at the file.  Every time you see "<xsl:template..." that is the start of a new Item Style.  There is one for each of the out-of-the-box Item Styles that show up in the Styles drop down in the Web Part Tool Pane.  For every custom Item Style that is needed, a newxsl:template> </xsl:template> block will have to be created.

1)    Scroll down to the bottom of the file. Copy the last xsl:template code block and paste it above the closing xsl:stylesheet tag.

2)    Change the name and match properties in the Template tag to a unique name of your choice:
            Format:
       <xsl:template name="NewsItemStyle" match="Row[@Style='NewsItemStyle']"        mode="itemstyle">
3)  Before we style any content, we need to have the web part pull in the content we want to display. Some content is already pulled in by default, such as Title.  For anything else that is not pulled by default, we need to tell the web part to get those fields. Steps to do that
A.       In the Content Query Web Part you have inserted on the page, click edit, and then click Export.
B.    In the File Download dialog box, click Save. In the Save As dialog box, type a name and location for the .webpart file. Click Save in the Save As dialog box to save the file.
C.    Open the saved file and search for “CommonViewFields” text, you can able to see tags like this,
                 <property name="CommonViewFields" type="string"></property>
D.  Add the list column name and along with column type you need in the new style.

 
And the Field type can be notified below,

E.  After adding the necessary fields inside the tag, save the file.
F.  Finally import this file as web part in moss2007.(Delete the previously added content query web part)

4)      Now customize the ITEMSTYLE.XSL file with necessary UI design format,
Example:
<div class="description">
    <xsl:value-of select="@Rollup" />
    <xsl:value-of select="@Body" />

</div>

Note:
Rollup and Body are the fields we added in the .WEBPART file.

5)      Complete code for NewsItemStyle has been written here.

<xsl:template name="NewsItemStyle" match="Row[@Style='NewsItemStyle']" mode="itemstyle">
  <xsl:variable name="SafeLinkUrl">
            <xsl:call-template name="OuterTemplate.GetSafeLink">
                 <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
            </xsl:call-template>
       </xsl:variable>
       <xsl:variable name="DisplayTitle">
            <xsl:call-template name="OuterTemplate.GetTitle">
                <xsl:with-param name="Title" select="@Title"/>
                <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
            </xsl:call-template>
       </xsl:variable>
       <xsl:variable name="RowNum" select="count(./preceding-sibling::*)" />
       <table>
  <tr>
  <td style="vertical-align:top;">
     <table>
  <!-- <xsl:if test="$RowNum &lt; 4"> //to restrict the number of rows-->
  <tr>
  <td valign="top">
  <a href="{$SafeLinkUrl}"><img border="0" height="50" width="80">
<xsl:attribute name="src"><xsl:value-of select="substring-before(substring(@Rollup, string-length(substring-before(@Rollup, 

'/St'))+1,string-length(@Rollup)),',')" />
  </xsl:attribute>
  </img>
  </a>
  </td>
  <td style="vertical-align:top;">
  <table>
  <tr>
  <td style="color:#3A80B8; font-family:'Century Gothic'; font-weight:bold; font-size:12px" valign="top">
  <xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
                <a class="NewsTitle" href="{$SafeLinkUrl}" title="{@LinkToolTip}">
                    <xsl:value-of select="$DisplayTitle"/> 
                </a>
  <br />
  <span style="color:#595959; font-family:Verdana; font-weight:bold; font-size:10px">
              <xsl:value-of select="ddwrt:FormatDate(@Created, 2057, 3)"/>
</span>  
</td>
  </tr>
  </table>
</td>
</tr>
  <!--</xsl:if>-->
     </table>
  </td>
  </tr>
       </table>       
 </xsl:template>


6)      Please “check in” the file and Now you can able to view you Custom style in Tool pane and under Presentation heading,

7)      Select all the necessary properties in Content query web part and publish the page.