locked
Problem in ItemUpdating event receiver RRS feed

  • Question

  • Hello all,

    I have created a form library and an event receiver on it. I face strange behavior when i debug the following code. When a debugger goes on itemToUpdate.Update(); line of code it again start debugging from the first line of code. What can be the problem ??? if i am missing something in the code that is the cause of this behavior please correct it. Or please suggest me to avoid this problem, Thanks in advance.

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

        using (SPSite oSPsite = new SPSite("http://portal.nrspbank.com/sites/hr")) {
            using (SPWeb oSPWeb = oSPsite.OpenWeb()) {

                SPList list = oSPWeb.Lists("Tasks");
                SPListItem MyList = properties.ListItem;

                if (Convert.ToBoolean(MyList("Approved_x0020_By")) == false) {
                    SPListItem itemToUpdate = list.GetItemById(MyList.ID);
                    SPUser AppUser = properties.Web.CurrentUser;
                    oSPWeb.AllowUnsafeUpdates = true;
                    itemToUpdate("Approved_x0020_By") = AppUser;
                    itemToUpdate.Update();
                    oSPWeb.AllowUnsafeUpdates = false;
                }

            }

        }

    }

    Monday, May 14, 2012 7:10 AM

Answers

  • Hello,

    you need to specify the eventfiring 

    public override void ItemUpdating(SPItemEventProperties properties)
    {
    EventFiringEnabled = false;
    
        base.ItemUpdating(properties);
    
        using (SPSite oSPsite = new SPSite("http://portal.nrspbank.com/sites/hr")) {
            using (SPWeb oSPWeb = oSPsite.OpenWeb()) {
    
                SPList list = oSPWeb.Lists("Tasks");
                SPListItem MyList = properties.ListItem;
    
                if (Convert.ToBoolean(MyList("Approved_x0020_By")) == false) {
                    SPListItem itemToUpdate = list.GetItemById(MyList.ID);
                    SPUser AppUser = properties.Web.CurrentUser;
                    oSPWeb.AllowUnsafeUpdates = true;
                    itemToUpdate("Approved_x0020_By") = AppUser;
                    itemToUpdate.Update();
                    oSPWeb.AllowUnsafeUpdates = false;
                }
    
            }
    EventFiringEnabled = true;
    
        }
    
    }

    With that, no event will be triggered when you perform an update in your code

    Hope this help!


    Best regards, Christopher.
    Blog | Mail


    • Edited by Christopher ClementEditor Monday, May 14, 2012 7:15 AM
    • Marked as answer by Rauf Ab Monday, May 14, 2012 7:28 AM
    • Unmarked as answer by Rauf Ab Monday, May 14, 2012 7:48 AM
    • Proposed as answer by dannyjessee Monday, May 14, 2012 9:57 AM
    • Marked as answer by Rauf Ab Tuesday, May 15, 2012 5:19 AM
    Monday, May 14, 2012 7:15 AM
    Answerer

All replies

  • Hello,

    you need to specify the eventfiring 

    public override void ItemUpdating(SPItemEventProperties properties)
    {
    EventFiringEnabled = false;
    
        base.ItemUpdating(properties);
    
        using (SPSite oSPsite = new SPSite("http://portal.nrspbank.com/sites/hr")) {
            using (SPWeb oSPWeb = oSPsite.OpenWeb()) {
    
                SPList list = oSPWeb.Lists("Tasks");
                SPListItem MyList = properties.ListItem;
    
                if (Convert.ToBoolean(MyList("Approved_x0020_By")) == false) {
                    SPListItem itemToUpdate = list.GetItemById(MyList.ID);
                    SPUser AppUser = properties.Web.CurrentUser;
                    oSPWeb.AllowUnsafeUpdates = true;
                    itemToUpdate("Approved_x0020_By") = AppUser;
                    itemToUpdate.Update();
                    oSPWeb.AllowUnsafeUpdates = false;
                }
    
            }
    EventFiringEnabled = true;
    
        }
    
    }

    With that, no event will be triggered when you perform an update in your code

    Hope this help!


    Best regards, Christopher.
    Blog | Mail


    • Edited by Christopher ClementEditor Monday, May 14, 2012 7:15 AM
    • Marked as answer by Rauf Ab Monday, May 14, 2012 7:28 AM
    • Unmarked as answer by Rauf Ab Monday, May 14, 2012 7:48 AM
    • Proposed as answer by dannyjessee Monday, May 14, 2012 9:57 AM
    • Marked as answer by Rauf Ab Tuesday, May 15, 2012 5:19 AM
    Monday, May 14, 2012 7:15 AM
    Answerer
  • Actually this was happening because i was writing code in "ItemUpdating" event which cause to run this event again and again. But when i write this code in

    "ItemUpdated" event it again put me in wonder. Debugger was executing each line of code twice and thrice in this event. I almost mad to figure out that what i am doing wrong.

    I explain to you that what i am going to achieve. I created a column in event receiver name "Approved by". Whenever a task is approved by approver a current user who is logged in is updated in "Approved by" column. Because by default in "Modified by" column a user "SHAREPOINT/system" is updating which i do not want in "Modified by" column, thats why i created by own column.

    Please tell me the workaround. i will be really thankful to you.

    Monday, May 14, 2012 7:54 AM
  • I didn't quite understand what you meant, but if you don't want ModifiedBy column to be modified try updating with :

     itemToUpdate.SystemUpdate(false);


    Please don't forget to mark the post as Helpful if you find my comment useful and as Answer if it solved your problem.
    INFOTEHNA Group, Document and Process Management Solutions ( www.infotehna.com )

    Monday, May 14, 2012 9:04 AM
  • The code will run multiple times in an "ItemUpdated" event as well unless you disable event firing the way Christopher Clement suggests.

    Danny Jessee
    MCPD - SharePoint Developer 2010
    MCTS - SharePoint 2010, Configuring
    dannyjessee.com/blog

    Monday, May 14, 2012 9:59 AM
  • Thanks,

    i tried exactly the same things that you are describing in your codes. Please look at the screen shots that how i tried to achive this but failed (my code is in vb) . This error is coming because ItemToUpdate.update hit two times. I will be million times of thanks if i solved my problem with you people help, thanks.

    Monday, May 14, 2012 12:53 PM
  • it's firing up Twice even with the "EventFiringEnabled" ?

    Can you check if your event is attached only one time to your list?


    Best regards, Christopher.
    Blog | Mail

    Monday, May 14, 2012 1:00 PM
    Answerer
  • Also, try putting EventFiringEnabled AFTER the invoke of base.ItemUpdated(properties).

    Base call resets some values (like cancellation/error status and message) so possibly it could revert you flag to true (not 100% sure of this, but you could try it).


    Please don't forget to mark the post as Helpful if you find my comment useful and as Answer if it solved your problem.
    INFOTEHNA Group, Document and Process Management Solutions ( www.infotehna.com )

    Monday, May 14, 2012 1:19 PM
  • Thanks Christopher,

    Your code is working nicely, but this code disable functioning the workflow and task does not approved and stop somewhere because EventFiringEnabled = false;. 

    But suddendly i recall my mind and when i come to know that "ItemUpdating" run two times (in my scanario) and when i disable EventFiring it restrict the second update and my workflow stops at this time. but when i enable EventFiring it still does not execute updates second time.

    I actually want to use the following code when "ItemUpdating" event runs second time. Please give me any work arround iam near to my solution, thanks.

    Following is the code which should execute when "ItemUpdating" event runs second time.

     if (Convert.ToBoolean(MyList("Approved_x0020_By")) == false) {
                   
    SPListItem itemToUpdate = list.GetItemById(MyList.ID);
                   
    SPUser AppUser = properties.Web.CurrentUser;
                    oSPWeb
    .AllowUnsafeUpdates = true;
                    itemToUpdate
    ("Approved_x0020_By") = AppUser;
                    itemToUpdate
    .Update();
                    oSPWeb
    .AllowUnsafeUpdates = false;
               
    }


    • Edited by Rauf Ab Tuesday, May 15, 2012 4:49 AM
    Tuesday, May 15, 2012 4:31 AM
  • I'm not sure of what you want

    if I've well understood you have one event receiver on item updating and you want it to be run 2 times? why this? Can't you do all your stuff in one?

    but

    if you want to do this you can create 2 event receiver on item updating , you set the "SequenceNumber" parameter and you set the eventfiringenable on both

    <SequenceNumber>10000</SequenceNumber>

    with that, one modification will trigger both event


    Best regards, Christopher.
    Blog | Mail

    Tuesday, May 15, 2012 7:41 AM
    Answerer
  • Thanks Christopher,

    Actually i figure out what was happening yesterday and today. My "ItemUpdating" event runs/execute two times. One under the user SHAREPOINT/system and one under the user who is actually login. When an event runs under SHAREPOINT/system, code execute multiple times randomly so i skipped the portion of code to execute under SHAREPOINT/system by using if/else. And when an "ItemUpdating" event runs second time, means under the user who is actually login, then it works perfectly and also your code works as i needed.

    So i achieve this thing in the above way, hope you understand now.

    If you experience these things as i experienced is correct then please acknowledge or please correct me,  I appreciate your help and patience.

    Tuesday, May 15, 2012 8:02 AM
  • I’ve created a form library and added the OOTB approval workflow on it. I performed some operation when the workflow is approved or rejected by using the below item updated event receiver code and its working fine if execute the code asynchronously.

    if

    (!string.IsNullOrEmpty(ApproversGroupName) && !user.Name.ToLower().Equals("system account"))

    {

    if

    && properties.ListItem[

    && properties.ListItem[

    (properties.ListItem.Fields.ContainsField("Outcome")"Outcome"] != null "Outcome"].ToString().Equals("Approved"))

    {

    //doing some operation here…

    }

    }

    But my client requirement is to execute the code synchronously, so I’ve added the below element in the element.xml

    <

    Synchronization>Synchronous</Synchronization>

    After that the properties.ListItem["Outcome"] returns null value.

    Also the code executed twice,

    First time fired by logged account then Outcome is null

    Second time fired by system account then Outcome field return a value.

    So please help me out this issue. Thanks.

    Wednesday, July 11, 2012 7:17 AM
  • Hello,

    Can you check the content of  properties.AfterProperties["Outcome"] ?

    you said you have added the synchronisation, have you recreated the list? if your event is firing twice maybe meens the event is attached twice to your list.


    Best regards, Christopher.
    Blog | Mail
    Please remember to click "Mark As Answer" if a post solves your problem or "Vote As Helpful" if it was useful.

    Wednesday, July 11, 2012 7:22 AM
    Answerer
  • Hi Christopher,

    I've checked that properties.AfterProperties["Outcome"]  returns null values.

    I was went to sitecollection feature in site settings and verfied that the event receiver added only one time for the specfic library.

    Do you have any other approach to test the event receiver whether attached one time or twice.

    Also not workfing after deleted and recreate it.

    Thanks

    Wednesday, July 11, 2012 7:52 AM
  • I found the solution for that issue, we can use the ExtendedProperties and get TaskStatus column. Please find the below code for your reference.

    public override void ItemUpdated(SPItemEventProperties properties)
    {
      taskStatus = getTaskStatus(properties);
      if (!string.IsNullOrEmpty(taskStatus) &&
          (string.Compare(taskStatus,"approved",true)==0)
         )
         {
           //code here
         }
    }
    private string getTaskStatus(SPItemEventProperties evtProp)
    {
      string taskStatus = String.Empty;
      try
       {
         if (evtProp.ListItem["ExtendedProperties"] != null)
         {
            taskStatus = evtProp.ListItem["ExtendedProperties"].ToString();
            if (taskStatus.Contains("ows_TaskStatus='"))
            {
              taskStatus = taskStatus.Substring(taskStatus.IndexOf("ows_TaskStatus='") + 16);
              if (!String.IsNullOrEmpty(taskStatus))
              {
                taskStatus = taskStatus.Substring(0, taskStatus.IndexOf("'"));
              }
              else
              {
                taskStatus = String.Empty;
              }
            }
            else
            {
              taskStatus = String.Empty;
             }
           }
          }
          catch (Exception ex)
          {
                    logToUls(ex.Message);
          }
          return taskStatus;
        }

    • Proposed as answer by SenthilGopal Monday, July 16, 2012 4:59 AM
    • Unproposed as answer by SenthilGopal Monday, July 16, 2012 4:59 AM
    Wednesday, July 11, 2012 11:00 AM