Monday, July 21, 2008

Properly Populating and Retrieving SharePoint Field Data

SharePoint uses a lot of field types that have different underlying schemas, delimiters and formats. I see a lot of people reverse engineer the field information and "hack" the data into the list using a string such as "1;#Title" for a lookup field. Well this isn't exactly best practice so I've put together a reference table below to assist in using the correct data types for populating or retrieving information from a SharePoint list.


Lookup Field


Field Class: SPFieldLookup
Field Value Class: SPFieldLookupValue

Populating Information:

item["FieldName"] = new SPFieldLookupValue("Title"); // SharePoint will do the lookup as long as the LookupValue's are unique
item.Update();
or
item["FieldName"] = new SPFieldLookupValue(1, "Title");
item.Update();

Retrieving Information:

SPFieldLookupValue itemValue = item["FieldName"] as SPFieldLookupValue;
int id = itemValue.LookupId;
string value = itemValue.LookupValue;

Multiple Lookup Field


Field Class: SPFieldLookup
Field Value Class: SPFieldLookupValueCollection

Populating Information:

SPFieldLookupValueCollection itemValues = SPFieldLookupValueCollection();
itemValues.Add(new SPFieldLookupValue(1, "Title"));
item["FieldName"] = itemValues;
item.Update();

Retrieving Information:

SPFieldLookupValueCollection itemValues = item["FieldName"] as SPFieldLookupValueCollection;
foreach (SPFieldLookupValue itemValue in itemValues)
{
int id = itemValue.LookupId;
string value = itemValue.LookupValue;
}

User Field


Field Class: SPFieldUser
Field Value Class: SPFieldUserValue

Populating Information:

web.EnsureUser(@"domain\username");
SPUser user = web.AllUsers[@"domain\username"];
item["FieldName"] = user;
item.Update();

Retrieving Information:

string currentValue = item["FieldName"].ToString();
SPFieldUser userField = list.Fields.GetFieldByInternalName("FieldName");
SPFieldUserValue itemValue = (SPFieldUserValue)userField.GetFieldValue(currentValue);
SPUser user = itemValue.User;

URL Field


Field Class: SPFieldUrl
Field Value Class: SPFieldUrlValue

Populating Information:

SPFieldUrlValue urlValue = new SPFieldUrlValue();
urlValue.Url = "http://www.google.com";
urlValue.Description = "Google";
item["FieldName"] = urlValue;
item.Update();

Retrieving Information:

SPFieldUrlValue urlValue = new SPFieldUrlValue(item["FieldName"].ToString());
string url = urlValue.Url;
string description = urlValue.Description;

Multiple Choice Field


Field Class: SPFieldMultiChoice
Field Value Class: SPFieldMultiChoiceValue

Populating Information:

SPFieldMultiChoiceValue itemValue = new SPFieldMultiChoiceValue();
itemValue.Add("Choice 1");
itemValue.Add("Choice 2");
itemValue.Add("Choice 3");
item["FieldName"] = itemValue;
item.Update();

Retrieving Information:

SPFieldMultiChoiceValue itemValue = new SPFieldMultiChoiceValue(item["FieldName"].ToString());
foreach (string choice in itemValue)
{
// value is in choice
}

11 comments:

Csam0003 said...

Hi this post is great!
However, is it possible to post soemthing on SPFieldUserMulti.

I wish to extract all the users from a multiselect Person field and give them permissions in an event handler.

Any ideas??Thank you

Anonymous said...

Hi, thanks for the heads up on this matter.

Following you method I'm getting this error "Value does not fall within the expected range" when I make this assignment:

listItem["ItemName"] = User;
//user is an SPUser obj

I filled the User variable with the steps that you provide and debugging it on VS2005 I can see that the value in it is correct. Something like {SPVM\bob}

Any help available?

Thanks,
Roger

Unknown said...

SPFieldMultiChoiceValue does not implement an iterator so you can not use a foreach loop to retrieve individual values.

Unknown said...

I agree with Dimitrie.

This is how you retrieve the possible choices from a multiple choice field:

SPFieldMultiChoice myChoiceField = new SPFieldMultiChoice(myItem.Fields, "myFieldnameString");

foreach (string choice in myChoiceField.Choices)
{
// do something with the value of the string choice here
}

Oli said...

You really did try this?

item["FieldName"] = new SPFieldLookupValue("Title");

And you don't have the "Value does not fall within the expected range." error??
Somehow, it seems to only accept strings that are castable as Integer. Like this would work:

item["FieldName"] = new SPFieldLookupValue("12345");

After executing the code just above, i check the value of item["FieldName"].LookupID and its 12345. So it basically converts the string to an Integer and places it in LookupID.

Oli said...

Also, what's "item" type? SPListItem?

dave.dolan said...

hah, I just implemented a bunch of string split and test for length stuff to parse out the value of a user field as an SPListItem instead of the strongly typed, and here I found that its as simple as casting it. Thanks! I can go back and fix my code now to do it the easy way.

--dave

Marlo said...

Here is some code which you can adapt for your use with UserMulti.

SPFieldUserValueCollection col = new SPFieldUserValueCollection();
string[] userarray = StringOfUsers.Split(',');
foreach (string username in userarray)
{
SPUser user = web.EnsureUser(username);
SPFieldUserValue uservalue = new SPFieldUserValue(web, user.ID, user.LoginName);
col.Add(uservalue);
}

item["UserMulti"] = col.ToString();

Anonymous said...

Great post! Could you please show how to retrieve a string value from a text Field? I tried to get it via field.GetFieldValue(string value), but what do I have to put in for string value?

Anonymous said...
This comment has been removed by the author.
ACrush said...

Ehm... Any ideas how to assign a constructed SPFieldUserValueCollection object to a UserMulti field in PowerShell?

$item["Field"] = $uvc doesn't seem to work whether you call ToString or not.

The assignment operator fails to understand the "999;#domain\username" syntax in this case. Complains that it cannot convert that string to SPFieldUserValue object.