Karine Bosch’s Blog

On SharePoint

Walkthrough 4 – Developing an Event Receiver for the ItemUpdating event


Data in SharePoint can change over time. You can also use event receivers to validate the data that the user wants to change. This walkthrough is based on the first one where I have a custom list with planets of our solar system. Users can change data like the number of moons or the distance to the earth, but they are not able to change the name of the planet.  To prevent users from changing the name of the planet, you can develop a ItemUpdating event receiver. This event occurs before the data is saved to the SharePoint list.

public override void  ItemUpdating(SPItemEventProperties properties)
{
    base.ItemUpdating(properties);
}

To check if the name of the planet is changed, you can compare the Title column before the changes with the Title of the changed item. The changed values can be retrieved from the AfterProperties of the incoming properties argument.  You could  think that the current values are stored in the BeforeProperties of the item but that’s not true: the BeforeProperties are unreliable at this point. Better use the ListItem property.

public override void  ItemUpdating(SPItemEventProperties properties)
{
       // The name of the planet may not be changed
       string currentPlanet = properties.ListItem["Title"].ToString();
       string newPlanet = properties.AfterProperties["Title"].ToString();

       if (currentPlanet != newPlanet)
       {
           properties.ErrorMessage = "The name of the planet cannot be changed.";
           properties.Status = SPEventReceiverStatus.CancelWithError;
           properties.Cancel = true;
       }
}

When the name of the planet is changed, the update is canceled and an error message is returned to the user. If the name isn’t changed, the changes are saved to the SharePoint list.

Before you can deploy the event receiver you have to change the elements.xml file to bind the UpdateAdding event receiver to all custom lists. Remember that if you want to develop event receivers for specific lists, you will have to work with content types.

<Elements Id="{F5610B81-A2E2-4957-ABF2-B8ECCD765AF3}"
          xmlns="http://schemas.microsoft.com/sharepoint/">
   <Receivers ListTemplateId="100">
      <Receiver>
         <Name>ItemAdding</Name>
         <Type>ItemAdding</Type>
         <SequenceNumber>1</SequenceNumber>
         <Assembly>UniverseEventHandlers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=841f382b41c47c60</Assembly>
         <Class>UniverseEventHandlers.PlanetItemEventReceiver</Class>
      </Receiver>
      <Receiver>
  <Name>ItemUpdating</Name>
  <Type>ItemUpdating</Type>
  <SequenceNumber>2</SequenceNumber>
  <Assembly>UniverseEventHandlers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=841f382b41c47c60</Assembly>
  <Class>UniverseEventHandlers.PlanetItemEventReceiver</Class>
</Receiver>

</Receivers>

</Elements>

Voila, you are ready to go.

Advertisements

33 Comments »

  1. very helpful

    Comment by asdfjkl; | March 13, 2010 | Reply

  2. Hi Karine, thanks for the interesting tutorial.

    Do you know how I can create a concatenated string string derived from the SharePoint document library metadata whenever a document is saved or edited.

    The purpose of this is to enforce a file naming convention whenever a document is saved to or edited in a Sharepoint Document Library:

    For example:
    Project ID + “ – “
    + Document Type + “(“
    + Tag + “)“
    + From + “ “
    + File Ref + “ “
    + “V” + Version

    The string for the Document Name in the document library would read:
    eg:
    0999 – Supplier Quotation (Furniture) Steve Smith QJD615 V3.0

    Any suggestions would be greatly appreciated.

    Kind Regards
    Gary

    Comment by Gary | September 5, 2010 | Reply

  3. Hi Gary,
    You can achieve this by writing an eventreceiver for the ItemAdding event. You can retrieve the properties from the list item using the incoming properties argument.
    Karine

    Comment by Karine Bosch | September 6, 2010 | Reply

  4. You are a life saver!!

    I was adding the actual code below an item added file and was wondering why itemupdating was not firing! ITS BECAUSE I FORGOT TO ADD THE XML!

    Thank you very very much.

    Comment by Eric Schrader | January 6, 2011 | Reply

  5. Thank you very Much Karine, Kindly have a look at the following code. I have a data sheet type list where in I have a field status (Drop Down) and Last Modified (Single Line Text). I am trying to update Last Modified field whenever I am updating the status field.

    public override void ItemUpdating(SPItemEventProperties properties)
    {
    base.ItemUpdating(properties);

    try
    {
    // The name of the planet may not be changed
    string currentPlanet = properties.ListItem[“Status”].ToString();
    string newPlanet = properties.AfterProperties[“Status”].ToString();

    if (currentPlanet != newPlanet)
    {
    SPListItem oItem = properties.ListItem;
    oItem[“Last Modified”] = DateTime.Today.ToShortDateString();
    oItem.Update();
    }

    }
    catch (Exception ex)
    {
    return;
    }
    finally
    {
    this.EventFiringEnabled = true;
    }
    }

    Element.xml

    EventReceiver1ItemAdding
    ItemAdding
    $SharePoint.Project.AssemblyFullName$
    StatusChangeER.EventReceiver1.EventReceiver1
    10000

    EventReceiver1ItemUpdating
    ItemUpdating
    $SharePoint.Project.AssemblyFullName$
    StatusChangeER.EventReceiver1.EventReceiver1
    10000

    How ever I am unable to get the updated value in the Last Modified column… Could you please help me to find the issue…

    ________________________

    One more related question : if my Last Modified field is of Date, can I use the line,
    oItem[“Last Modified”] = DateTime.Today;

    Thank you,,,

    Comment by msbuzzz | November 11, 2011 | Reply

  6. My element.xml did not appear correctly in the comment. Please not that ListTemplateId=”120″
    Thank You…

    Comment by msbuzzz | November 11, 2011 | Reply

  7. msbuzz, you can make your Last Modified field a Date field and use DateTime.Today to store the date. But I don’t think that will solve your issue of the event handler.

    Comment by Karine Bosch | November 13, 2011 | Reply

  8. msbuzz, it is possible you have problems because you don’t use the this.DisableEventFiring(); at the beginning of your code and this.EnableEventFiring(); at the end. This will prevent the event handler from firing again and again when you try to fill out data in the Last Modified field.
    Also use item.SystemUpdate(); instead of item.Update().

    Comment by Karine Bosch | November 13, 2011 | Reply

  9. Thank you Karine, now i could able to get the date in last modified field. However problem is it is throwing a save conflict. Since I am updating the last modified date in the event receiver , my status field is not storing, it tells that another user has already updated the field and i am forced to discard my status field changes !!

    Thanks !!

    Comment by msbuzzz | November 16, 2011 | Reply

  10. I have tried the same as you suggested, however my ItemUpdating Event never fires. I tried using the ItemUpdated event and that works just fine. I need to get the itemUdpating event working. What do I do?

    -Pradeep

    Comment by Pradeep Nayak | November 30, 2011 | Reply

    • Hii Pradeep.
      Where you able to get the ItemUpdating event receiver working? I am having the same issue as yours.

      Comment by shilpa | March 7, 2012 | Reply

      • I was never able to:( let me know if you find a solution

        Comment by Pradeep Nayak | March 8, 2012

  11. Love the planet reference!
    FYI:
    To target 1 list, change elements xml from ListTemplateId to ListUrl

    Also Yes/No fields in the AfterProperties are stored as “0” and “1” which will mess with bool.parse

    Cheers!

    Comment by Xopher | January 24, 2012 | Reply

  12. It removed my xml example to target a single list
    Receivers ListUrl=”Lists/Customers”

    Comment by Xopher | January 24, 2012 | Reply

  13. Hello, Karine!

    I have WSS 3.0 and i would like to do when the user add attachment then all of attachments was numbered and sorted by date! Please tell me is it possible to do it with only Sharepoint Designer?

    Comment by Konstantin | July 10, 2012 | Reply

    • Hi Konstantin,
      You could create some custom view, but I’m affraid this is not possible with SharePoint Designer.

      Comment by Karine Bosch | July 13, 2012 | Reply

  14. Hi Karine. I have a custom logic for Save event on the custom form that has info from several lists. My event receiver is updating some fields in one list on ItemUpdating() and once that done I’m using newly populated information to display back on the form. The problem is date column value is updated while i’m inside the receiver code but then it’s ‘null’ when i’m trying to retrieve it. However, Current user name is populated correctly. Any ideas why it could be happening?

    Comment by Vera | January 28, 2014 | Reply

    • Is it the Modified column you’re talking about?
      Kind regards,
      Karine Bosch

      Comment by Karine Bosch | January 28, 2014 | Reply

      • It kind of is but it is Modified Date for one of the custom columns that I have. So basically i’m keeping track of one this specific column was modified and by who. The user populates just fine but date is not.

        Comment by Vera | January 28, 2014

      • If you keep track of the Modified Date yourself, you should be able to use DateTime.Now, no?

        Comment by Karine Bosch | January 28, 2014

      • I did use The DateTime.Now to populate the column value but when I’m trying to retrieve the value taht was just populated it returns ‘null’

        Comment by Vera | January 28, 2014

      • Hi Vera, I’m afraid I need the whole code snippet to be able to see what’s wrong.
        Karine

        Comment by Karine Bosch | January 28, 2014

      • I can send you the Event receiver code but i don’t think it might be the issue. I’m using SPMetal to populate the model for custom lists. Once event Receiver logic updates the values I have to retrive the values and populate them to the label on the page

        Comment by Vera | January 28, 2014

      • You can also post it on the forum, to get an higher chance to get an answer to your problem.

        Comment by Karine Bosch | January 28, 2014

  15. Hi Karine,

    I have a date field(DateTime) in my list. And I want to add conditions for some dates, like, if the user is selecting some particular dates, I want to throw an error.
    How can I make a condition like “string currentPlanet = properties.ListItem[“Title”].ToString();” for DateTime.

    Comment by Shemin Daniel | July 31, 2014 | Reply

    • Hi Shemin,
      DateTime fields have a particular format in SharePoint. If you need to convert a SharePoint date to a DateTime variable, you have to use the function SPUtility.CreateDateTimeFromISO8601DateTimeString:
      DateTime myDate = SPUtility.CreateDateTimeFromISO8601DateTimeString(properties.ListItem[“”].ToString();

      Comment by Karine Bosch | July 31, 2014 | Reply

      • Thanks a lot Karine.

        Comment by Shemin Daniel | August 1, 2014

      • I have a list with datetime control(Date and Time) column.

        Resolution Date is my column(Date and Time: 9/19/2012 9:00 AM FORMAT)

        DateTime myDate = SPUtility.CreateDateTimeFromISO8601DateTimeString(properties.ListItem[“Resolution Date”].ToString()); OR DateTime myDate = DateTime.Parse(properties.AfterProperties[“Resolution Date”].ToString());

        if (myDate.Date.Equals(Convert.ToDateTime(“2014-08-05 08:00:00”).Date)) or//if (myDate.Date.Equals(Convert.ToDateTime(“2014-08-05 08:00:00”).Date))
        if (dtAfter.Date.Equals(Convert.ToDateTime(“1/1/2014”).Date))
        {
        properties.Status = SPEventReceiverStatus.CancelWithError;
        properties.Cancel = true;
        properties.ErrorMessage = “Today is a Holiday(All Saint’s Day)”;
        }
        I am trying with these, however I am getting the error nullreferenceexception was unhandled error.

        Please help

        Comment by Shemin Daniel | August 5, 2014

      • First thing to do is put a breakpoint on the first line and try to find out which line is giving your the null reference exception.

        Comment by Karine Bosch | August 6, 2014

  16. I have tried both “DateTime myDate = SPUtility.CreateDateTimeFromISO8601DateTimeString(properties.ListItem[“Resolution Date”].ToString()); ” and “DateTime myDate = DateTime.Parse(properties.AfterProperties[“Resolution Date”].ToString());”. And here I am getting the error

    Comment by Shemin Daniel | August 6, 2014 | Reply

  17. I need an event receiver to check if the user added to the user field is a member of say “xyz” group, if yes then resolve it in people picker else do not resolve it. Can you please help me with that

    Comment by Rohit Dhiman | March 28, 2016 | Reply


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: