Wednesday, October 19, 2011

Taxonomy Update Scheduler triggers list item event receivers in TaxonomyHiddenList

Update 2011-11-23: originally this post was written under impression (and it was confirmed by tests) that event receivers are triggered for any custom list which has managed metadata fields. However today my colleague found that event receiver is triggered only in TaxonomyHiddenList, but not on the exact supplier custom lists. The reason why my tests worked – is because event receiver was provisioned using elements manifest to all lists with specified list template id = 100 (custom lists). And guess what list template id is used for TaxonomyHiddenList – yes exactly the same 100. So my event receiver was triggered not for the custom list, but for TaxonomyHiddenList itself (it is enough to trace title of the parent list in the debugger to see it). Fortunately – it was also Ok for our case, because based on this information we also were able to determine what term from what term set was changed and force Update event on the lists items which contain this term. So everything what is wrote below is correct, but with assumption that it says about TaxonomyHiddenList only.

Taxonomy Update Scheduler is OTB Sharepoint timer job which synchronizes changes from Term store into Sharepoint web site. This timer jobs pushes changes from the Term store into TaxonomyHiddenList (list which contains all used managed metadata in the site). Here is the good explanation of the internal mechanisms in Sharepoint taxonomy.

As you probably know you can’t use managed metadata as lookup column when add lookup field into the Sharepoint. In our case data was stored in term store, but we also needed to create lookup column on this data in list A into another list B (managed metadata field was not the only one column in the list A – there were several fields, that’s why we needed to use lookup and couldn’t add managed metadata to the list B directly). As workaround we added plain text column and updated value in this column via custom item event receiver in ItemUpdated event.

There was one problem with this solution: customers wanted to update data only in one place (term store). After that changes should be automatically propagated into the custom list (into text field). As I already said, changes are not propagated from term store into Sharepoint site immediately. It is done by Taxonomy Update Scheduler timer job. Testing showed that Taxonomy Update Scheduler triggers our custom item event receivers (and it was completely ok for us).

For testing you can use simple event receiver which logs all events:

   1: public class EventReceiver1 : SPItemEventReceiver
   2: {
   3:     public static object lockObj = new object();
   5:     private void log(SPItemEventProperties p)
   6:     {
   7:         lock (lockObj)
   8:         {
   9:             var version = p.ListItem.Versions[0];
  10:             File.AppendAllText("c:/temp/log_events.txt", string.Format("{0}:\t{1}\t{2}\t{3}\t{4}{5}",
  11:                 DateTime.Now, new StackTrace().GetFrame(1).GetMethod().Name,
  12:                 version.Level, version.VersionId, version.VersionLabel, Environment.NewLine));
  13:         }
  14:     }
  16:    public override void ItemAdding(SPItemEventProperties p) { log(p); }
  17:    public override void ItemUpdating(SPItemEventProperties p) { log(p); }
  18:    public override void ItemDeleting(SPItemEventProperties p) { log(p); }
  19:    public override void ItemCheckingIn(SPItemEventProperties p) { log(p); }
  20:    public override void ItemCheckingOut(SPItemEventProperties p) { log(p); }
  21:    public override void ItemUncheckingOut(SPItemEventProperties p) { log(p); }
  22:    public override void ItemFileMoving(SPItemEventProperties p) { log(p); }
  23:    public override void ItemAdded(SPItemEventProperties p) { log(p); }
  24:    public override void ItemUpdated(SPItemEventProperties p) { log(p); }
  25:    public override void ItemDeleted(SPItemEventProperties p) { log(p); }
  26:    public override void ItemCheckedIn(SPItemEventProperties p) { log(p); }
  27:    public override void ItemCheckedOut(SPItemEventProperties p) { log(p); }
  28:    public override void ItemUncheckedOut(SPItemEventProperties p) { log(p); }
  29:    public override void ItemFileMoved(SPItemEventProperties p) { log(p); }
  30: }

Also we will need term set for testing:


Now lets create new item in the custom list with this event receiver and tag it with “English” language:


Then go back to the Term store and change “English” term to “English UK”:


If you will go to the default list view and refresh it, you will see that it will still have “English” tag. Then go to Central Administration > Job Definitions and force run of Taxonomy Update Scheduler job. After that field will have “English UK”:


Now let’s check log_events.txt file:


19.10.2011 20:24:50:    ItemAdded    Published    512    1.0

// item was added


10/19/2011 8:25:32 PM:    ItemUpdating    Published    512    1.0
10/19/2011 8:25:32 PM:    ItemUpdated    Published    512    1.0

// item was updated by Taxonomy Update Scheduler: "English" term was changed to "English UK"


As you can see ItemUpdating and ItemUpdated events were triggered when we changed term name automatically.

No comments:

Post a Comment