ItemUpdated called twice in event receiver on document library, can we differentiate between both the cycles?

Respondido ItemUpdated called twice in event receiver on document library, can we differentiate between both the cycles?

  • 2012年7月16日 13:57
     
     

    My doc lib row has a custom choice column that we need to set value while we add a file which has same name with a file already in doc lib.

    Steps:

    1. click on 'add document' - > file selection window will appear

    2. select file to upload, it will upload the file, hence will ItemUpdated, then in second window it will ask choice column to select value.

    3. It will call ItemUpdated.

    Its evident that doc lib always upload the file before assigning attributes to it. I need a way (may be a property) to distinguish between two itemUpdated iteration.



すべての返信

  • 2012年7月16日 14:13
     
     回答済み コードあり

    Hello!

    You can disable the ItemUpdated event firing while choice column is being changed. For example, I created the following class, which can be used outside of event handlers.

    public class EventDisabler : SPEventReceiverBase
        {
            public void DisableEvents()
            {
                DisableEventFiring();
            }
            public void EnableEvents()
            {
                EnableEventFiring();
            }
        }

    Your code for choice field updating may look like:

    EventDisabler eventDisabler = new EventDisabler();
    eventDisabler.DisableEvents();
    
    SPListItem doc = // get list item
    doc["choice field"] = "some value";
    doc.Update();
    
    eventDisabler.EnableEvents();
    So, in this case the second ItemUpdated won't be called.

    .Net Follower (http://dotnetfollower.com)

    • 回答としてマーク ShahidAliK 2012年7月28日 9:44
    •  
  • 2012年7月16日 14:51
     
     回答済み

    Hi Shahid,

    Thank you for your query. Events firing twice, eh?? I remember battling through these.

    1. Ensure you are following right use of after/before properties

    http://www.synergyonline.com/Blog/Lists/Posts/Post.aspx?ID=122

    2. Not sure what event in particular are you using since you have not shared your code, since you mention updated, I think it is best if you try using itemUpdating event ONLY for this operation. The above link will give you the framework for using after/before properties to access values in your choice column.

    On a final note, step 1 is itemAdded event followed by itemAdding and your step 2 is infact itemUpdating event - during this time the meta data of your sharepoint document library is not accessible and only on OK of 2nd step will fire first itemUpdating and then followed by itemUpdated. Referencing

    http://www.codeproject.com/Articles/37985/MOSS-For-Developers-Part-3-Event-Handlers-for-Deve

    "Only default content type properties are present in the Add phase. Additional properties (fields) of the specified content type are added only in the Update phase. Therefore, best practice is to avoid firing Add events with a specified content type ID. Instead, set the content type to the default content type in the Add phase. The content type can subsequently be changed in the Update phase. An alternative is to register the events at the list level."

    Furthermore, for your reference kindly bookmark

    http://platinumdogs.me/2012/01/05/sharepoint-2010-document-lifecycle-event-receiver-point-of-view/

    PS - Sharepoint 2010 "I think" is still applicable to Sharepoint 2007 event receivers (moderators kindly correct me if I am wrong).

    Hope this helps and clarifies your understanding.

    Thanks

    • 回答としてマーク ShahidAliK 2012年7月28日 9:44
    •  
  • 2012年7月28日 9:50
     
     

    Hi All,

    Thank you both of you for quick reply, but my architect gave me following approach to fix it.

    I personally dont think that its flawless but worked. We are keeping track of time updated should be < 10 seconds.

    I know this is not thread safe but in my case only one person at a time would update the doc lib.

    DataSourceType is my choice column in doc lib.

    public class ExecutiveDashBoardLibEventReceiver : SPItemEventReceiver
        {
            Model.DashboardDocumentHelper documentHelper = new Model.DashboardDocumentHelper();
            static Dictionary<string, DateTime> DataSourceDictionary = new Dictionary<string, DateTime>(StringComparer.CurrentCultureIgnoreCase);

            public string DashBoardDocLibColumn_DataSourceType
            {
                get { return "DataSourceType"; }
            }

            public override void ItemUpdated(SPItemEventProperties properties)
            {
                if (properties.ListItem["DataSourceType"] == null) return;

                string fileURL = properties.ListItem.File.Url;
                fileURL = fileURL.Substring(fileURL.LastIndexOf('/') + 1);


                if (!DataSourceDictionary.ContainsKey(fileURL))
                {
                    DataSourceDictionary.Add(fileURL, DateTime.Now);
                    CopyAndRunImport(properties);
                }
                else
                {
                    DateTime lastLoaded = DataSourceDictionary[fileURL];

                    if (Convert.ToInt32((DateTime.Now - lastLoaded).TotalSeconds) > 10)
                    {
                        DataSourceDictionary[fileURL] = DateTime.Now;
                        CopyAndRunImport(properties);                    
                    }
                }

                base.ItemUpdated(properties);
            }

            public void CopyAndRunImport(SPItemEventProperties properties)
            {
                // My Custom code where uploaded file is dumped on file system.
            }
        }

                               
    • 編集済み ShahidAliK 2013年4月1日 6:11 update
    •