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. 🙂
One comment on “Easily accessing Lookup and User fields”
Thank you! this helped me!