Aug 162011
 

Writing code to get or set data in a lookup field (SPFieldLookup) or its descendant the User field (SPFieldUser) can be a real pain in the eyes. Thankfully there’s a handy couple of classes that can make life easier.

If you’ve ever frowned at “;#” delimiters, and begrudgingly twisted a for clause to check every other line, then you should most definitely read on.

A bit of background

Most complex field types have a Value class; a class that handles serialising and deserialising an item’s data for that field. If the field can have multiple values then there is often also a Collection class (a generic collection in the form List<Value>).

For lookups these classes are called SPFieldLookupValue and SPFieldLookupValueCollection. For User selections these are SPFieldUserValue and SPFieldUserValueCollection.

Getting single items

If you only have one value in a lookup, then this can be accessed using the following:

SPListItem item = SPContext.Current.List.GetItemById(1);
 
if (item["LookupField"] != null)
{
     string fieldValue = item["LookupField"].ToString();
     SPFieldLookupValue value = new SPFieldLookupValue(fieldValue);
     int lookupListItemID = value.LookupId;
     string lookupListValue = value.LookupValue;
}

Not a single split string in sight. To do the same for a single user field, you do the following:

SPListItem item = SPContext.Current.List.GetItemById(1);
 
if (item["UserField"] != null)
{
     string fieldValue = item["UserField"].ToString();
     SPFieldUserValue value = new SPFieldUserValue(SPContext.Current.Web, fieldValue);
     SPUser user = value.User;
}

The SPWeb passed into the constructor above is used to resolve the User; if you’re writing cross-site code make sure you pass a Web that recognises the User.

Setting single items

Setting lookups is quite straight forward:

SPListItem item = SPContext.Current.List.GetItemById(1);
int id = 1;
item["LookupField"] = new SPFieldLookupValue(id, string.Empty);
item.Update();

id is the item ID in the lookup list, and the string.Empty is the optional (as far as I can tell) display value. The display value is populated using the ID once the item is updated, so we needn’t bother getting it ourselves.

Setting a single user field couldn’t be easier, and requires no special tools, classes, or qualifications:

item["UserField"] = SPContext.Current.Web.CurrentUser;

Multiple items

Now we’re getting into more interesting territory. Multiple choice Lookups can be accessed using the previously-mentioned SPFieldLookupValueCollection. This is a collection of SPFieldLookupValue objects that each represent one of the values.

The collection can be used to get information like this:

SPListItem item = SPContext.Current.List.GetItemById(1);
if (item["LookupField"] != null)
{
     string fieldValue = item["LookupField"].ToString();
     SPFieldLookupValueCollection values = new SPFieldLookupValueCollection(fieldValue);
     foreach (SPFieldLookupValue value in values)
     {
         int lookupListItemID = value.LookupId;
         string lookupListValue = value.LookupValue;
     }

}

And to set the item data like this:

SPListItem item = SPContext.Current.List.GetItemById(1);
SPFieldLookupValueCollection values = new SPFieldLookupValueCollection();
values.Add(new SPFieldLookupValue(1,string.Empty));
values.Add(new SPFieldLookupValue(3,string.Empty));
item["LookupField"] = values;
item.Update();

The SPFieldUserValueCollection is used in almost exactly the same way. The only differences are that the constructors require an SPWeb, and SPUser.ID is used for the LookupID.

Pretty neat

Well, I thought so.

All this was probably old news to some, but it was a Christmas stocking of happy surprises for me when I found it. :)

  2 Responses to “Easily accessing Lookup and User fields”

  1. In order to avoid alternate line processing I used RegEx.Split, which splits on a multi character string

    string[] parts = Regex.Split(temp, “;#”);

    But I like your code better

  2. nice!!

Leave a Reply

%d bloggers like this: