Using the UI, it is quite easy to add and remove users. (Note: You must make sure the column allows multiple selections to add more than one user). But how would this be done programmatically using the SharePoint Object Model? This is a bit more complex since we somehow need to add or remove items from a list (e.g. both Robert King and Laura Callahan). And this list is stored in a single field’s value.
The answer is to use a class called SPFieldUserValueCollection. As you’ll guess, it’s a collection of SPFieldUserValue objects, and each SPFieldUserValue object basically represents a single user (SPUser) or group (SPGroup) from your site collection.
Here’s some code to help explain what I mean. This code retrieves a single item from the Tasks list and iterates through each field user value.
//Get a handle to our Tasks list
SPList tasks = web.Lists["Tasks"];
//Select first in the list
SPListItem task = tasks.Items[0];
//Access value from AssignedTo and cast to SPFieldUserValueCollection
SPFieldUserValueCollection AssignedTo = (SPFieldUserValueCollection)task["AssignedTo"];
foreach (SPFieldUserValue fuv in AssignedTo)
{
Console.WriteLine("LookupId = {0}, LookupValue = {1}", fuv.LookupId, fuv.LookupValue);
}
foreach (SPFieldUserValue Value in Values)
{
if (User != null)
{
SPUser User = Value.User;
Users.Add(User);
}
else
{
SPGroup Group = Web.Groups.GetByID(Value.LookupId);
Groups.Add(Group);
Users.AddRange(Group.Users);
}
}
This results in the following console output for the single task shown above:
LookupId = 19, LookupValue = Robert King
LookupId = 16, LookupValue = Laura Callahan
For those curious, you can also take the value of the field and output as a string using syntax like: task[“AssignedTo”].ToString(). If you do, it will look like this:
19;#Robert King;#16;#Laura Callahan
(Note: this is the same way that a Lookup column works. See this well-written blog article for more info on this.)
So, you should have a basic idea on how this is internally stored within SharePoint. Let’s now get to the code which actually adds or remove users. To do this, I wrote two simple helper methods that you’re welcome to use. Here is the one that adds a user or group:
void AddPrincipal (SPListItem item, string column, SPPrincipal principal)
{
SPFieldUserValueCollection fuvc = (SPFieldUserValueCollection)item[column];
fuvc.Add(new SPFieldUserValue(item.ParentList.ParentWeb, principal.ID, principal.Name));
item[column] = fuvc;
item.Update();
}
It’s pretty straight forward. The reason I called the method AddPrincipal is that SPPrincipal is the base class for SPUser and SPGroup. This allows it to be used for either object type. The method takes the SPListItem, the name of the column and the SPPrincipal. Here’s how we would call it from our code:
SPUser user = web.SiteUsers["synergy\\lcallahan"];
AddPrincipal(task, "AssignedTo", user);
Calling it to add a group is the same. Here is an example:
SPGroup group = web.SiteGroups["Home Owners"];
AddPrincipal(task, "AssignedTo", group);
Removing is a little trickier as we must first find the SPPrincipal. Here is the code:
void RemovePrincipal(SPListItem item, string column, SPPrincipal principal)
{
SPFieldUserValueCollection fuvc = (SPFieldUserValueCollection)item[column];
foreach (SPFieldUserValue value in fuvc)
{
if (value.LookupId == principal.ID)
{
fuvc.Remove(value);
item[column] = fuvc;
item.Update();
break;
}
//optionally throw an exception if not found
//throw new System.ArgumentException ("Principal not found");
}
}
Calling into the method is very simple. Here we are removing a user and a group.
RemovePrincipal(task, "AssignedTo", user);
RemovePrincipal(task, "AssignedTo", group);