tags:

views:

2831

answers:

2

I'm writing an ItemAdding handler for a SharePoint list, and the list contains multi-user fields. Since the SPItem is not actually available at this point, I think I'm relegated to using the string that comes back from the SPItemEventDataCollection. That string will look something like this when user1, user2, and user3 are present:

1;#MYDOMAIN\user1;#4;#MYDOMAIN\user2;#10;#MYDOMAIN\user3

I'd like to convert this into an array of SPUser objects in order to pass it into another existing method. Is there any SharePoint built-in way to handle these strings, or am I relegated to parsing this string?

Also, assuming I need to deal with this string, it looks like the integer tokens here always correspond to the domain\username that follows. Are there any cases where this will not be true and either the integer or the domain\username are missing or otherwise incorrect? Would it be safe to just use the numbers and use SPWeb's SiteUsers.GetByID(id) method? In a handful of tests I can't get that to fail, but it seems weird that both the numeric and string data would be included if they're totally redundant.

Thanks!

+1  A: 

This works for me getting a SPSuser from a user field It should be the same thing for extracting it from event data.:

private SPUser getGroup(SPListItem item, string fieldName)
        {
            string fieldValue = item[fieldName] as string;
            if (string.IsNullOrEmpty(fieldValue)) return null;
            int id = int.Parse(fieldValue.Split(';')[0]);
            SPUser user = item.Web.AllUsers.GetByID(id);
            return user;
        }

The integer refers to the id of the user in the local SPWebs's user database. This is, however not synced, so the user may have been deleted from the user database since the list item was saved.

Øyvind Skaar
Thanks. I basically ended up taking this route, but with the added wrinkle that there are potentially multiple users in the field's value. One weird thing is that with a single user in my field, there is only the numeric value in the field rather than the ";"-delimited value. Still seems to work.
Chris Farmer
+3  A: 

SPFieldUserValueCollection does exactly what you're looking for. Its constructor accepts an SPWeb and string of users. The SPFieldUserValue items in the collection provide a User property that returns the corresponding SPUser objects for the web.

private void ProcessUsers(SPListItem item, string fieldName)
{
  string fieldValue = item[fieldName] as string;
  SPFieldUserValueCollection users = new SPFieldUserValueCollection(item.Web, fieldValue);

  foreach(SPFieldUserValue uv in users)
  {
    SPUser user = uv.User;
    // Process user
  }
}

The SPFieldUser type inherits its behavior from the standard SPFieldLookup, which also stores both ID and Title and has a corresponding SPFieldLookupValueCollection. The ID supports (weak) referential integrity while the cached Value allows for quick queries.

dahlbyk