Accessing SharePoint lookup fields values in item receivers - some pitfalls.

Hi!

Recently I was playing with synchronous item event receivers and lookup fields and found some interesting behavior in different situations. I'll try to describe some pitfalls that I faced when develop item receivers for SharePoint.

So, lookup fields. When you try access to a lookup field in such events as Adding or Updating you may to have lookup value. But AfterProperties always contain only lookup Id, if you want to get lookup value you must query item by id. Imagine you have a list named "Software", it has title field and category lookup field (now we have 19 category types in "Category" list). When we try to add new item in "Software" list in ItemAdding event we can see:

Where "18" is an Id of category. And ItemAdded:

So, when use class SPFieldLookupValue, in ItemAdding event LookupValue equal to null (in AfterProperties) and not null in ItemAdded(in ListItem).

Let's try to update this item:

Situation is very similar - in AfterProperties we have an item Id (LookupId in SPFieldLookupValue class, LookupValue is null), and value in ListItem. In ItemUpdated event as you may know we will have both lookupId and LookupValue. Be aware of this SharePoint behavior.

Let's go further. Category is not required field, what if we leave it blank? Not surprise that we can see something like this (ItemAdding):

And in ItemUpdating:

So, if you didn't specify lookup, it equal to null or string.empty depending on using AfterProperties or ListItem. In receiver you may check if specific lookup field equal to null and perform something usefull depending on situation. And it will be worked.. until items count in lookup field will be less than 20. Than happens something strange - your code will be work fine for Firefox, Chrome, etc, but not for IE. Hmmm...very strange.

The answer is that when items count in lookup list more than 19, IE renders lookup field differently. When items less than 20, it renders html select element, but when items more than 19, it renders input and img, that simulate select element (you can verify this using IE developers tools). The reason for this is to enable "auto suggest/filtering" feature as you type values in the textbox (SharePoint register a couple of events to this input and image and perform all required javascript code for auto suggest/filtering). Its cool, but what happen with our receivers? Here is an answer:

In ItemAdding we have "0" in category, but this isn't an item's Id, this is null, and this behavior we have only in IE. If you before check in your item event receiver only for null lookup field, your code will become working incorrectly, when items number in lookup list more than 19. And when we try to update item in IE:

It's not expected behavior. But why this happens? When lookup rendered as select and we leave it blank, browsers posts "0" as select value (you can test it using fiddler), and SharePoint handle it correctly - in item receiver we have null or empty string for lookup value. But when items count more than 19, IE renders input, and in post back input also sends "0" when we leave lookup blank, but in this situation SharePoint works not correctly and set "0" as lookup Id, but when we try get item by this Id, we of course get an exception.  In your environment all can work great, but in production you may faced with complex error and spend much time to find a reason of it. So, be aware of this SharePoint behavior and make required spelling for all situations.

Update: issue with "0" in after properties reproduced on my SharePoint with August 2010 CU, it may fixed in older updates, I try to test it in future.

Hope this helps.