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

by Kai 6. July 2011 03:44

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.

Tags: ,

Lookup | SharePoint 2010

Comments (4) -

Martin
Martin
7/11/2011 2:35:49 AM #

Hi Kai,

nice Post. I have the the same issue on my  sharepoint server with CU March  2011. On my old system with CU October 2010 all is fine. Which SharePoint version do you use? SP1? If not could you verify that the problem exists with SP1.

Thank You
Martin

Reply

Kai
Kai
7/17/2011 2:59:07 AM #

Hi Martin!
Sorry for long reply. It is very strange that in CU March 2011 this issue appear again.
I use rather old version of sharepoint 2010 - it includes only August CU. I am not plan to install SP1 on my machine  yet, but I will try to install SP1 to virtual machine and test this issue.
So, I've been updated post, to reflect version of sharepoint that I use and in future I test if it reproduced in SP1.  

Reply

Dewa
Dewa
11/9/2011 11:58:07 PM #

Hi Kai

Nice post you have here, by the way, I have a problem and maybe you can help me to solve it.
I  have two List Category (Title, CategoryNo) and Rack (Title, refCategory, RackNo), with refCategory is a lookup field to Category.

what i'm trying to do is when i create new item in Rack, i want RackNo value is assign with Rack Title + CategoryNo
but when i use properties.AfterProperties['refCategory'] in ItemAdding method i only got the ID not the CategoryNo..

my question is how can i get the CategoryNo while i'm adding the item? so that in the ItemAdding method i can get properties.AfterProperties['RackNo'] = properties.AfterProperties['Title'].toString() + "/"+ [the_CategoryNo]


Thank you Kai

Reply

admin
admin
11/10/2011 5:20:08 AM #

Hi, Dewa

but when i use properties.AfterProperties['refCategory'] in ItemAdding method i only got the ID not the CategoryNo..

Yes, this is Id of item in your lookup list (Category), so all you need is get item by Id from your CategoryNo list, and then get field value. Something like this:

  var list = web.Lists["Category"];
  int id;
  if(int.TryParse(properties.AfterProperties['refCategory'].ToString(), out id))
  {
     var item = list.GetItemById(id);
     var categoryNo = item["CategoryNo"];
  }

  Hope this helps.

Reply

Pingbacks and trackbacks (2)+

Add comment

biuquote
  • Comment
  • Preview
Loading