If you are setting MOSS User Profile properties, there is a bit of a gotcha when dealing with multi-value properties. Normally, you'd do something like:

UserProfileManager oManager = GetUserProfileManager();

UserProfile oProfile = oManager.GetUserProfile(sUsername);

oProfile["SomePropertyName"].Value = "This is a nice value to set";

If you try this then, happily, it will probably work. That is unless you have a multi-value property. Well - it will work if you have a multi-value property, as long as you are only setting a single value.

Let me explain.... it looks at first glance as if the property is just an object with a 'Value' property accessed via the indexer, it's a little more than that. The property is, in fact, a UserProfileValueCollection object. Indeed, apparently it's a UserProfileValueCollection object even if it's not a multi-value field - it just has a default indexer to the first object in the collection so that you'd never realise it was a collection. This is why the syntax I showed above for a single value worked OK.

So when will it not work? Well, try and do this with a multi-value property when you have a constrained choice list (comma-separated in this case):

oProfile["SomePropertyName"].Value = "Multivalue 1, Multivalue 2, Multivalue 3";

It will throw an exception along the lines of 'thats not a valid option'. This is because it is trying to find an option in the choice list that matches the whole string. It is not 'intelligent' enough to try and break down the string into separate values.

(side note - the 'Separator' property of the Property object, which is of type MultiValueSeparator enum, appears to be only related to how the UI itself captures or presents the data. Behind the scenes, the data is stored in a collection and the Separator property is pretty much redundant. In fact, you could build your own UI elements to manipulate the value collection and you can totally ignore that Separator property, if you wished.)

So, how to fix it? Well, luckily its actually very simple. In the above example, you'd just do this:

((UserProfileValueCollection)oProfile["SomePropertyName"]).Add("Multivalue1");

((UserProfileValueCollection)oProfile["SomePropertyName"]).Add("Multivalue2");

((UserProfileValueCollection)oProfile["SomePropertyName"]).Add("Multivalue3");

If you wanted to be very clean about it, or it was an automated process which didn't know what type the property was, then you could use the following technique to check for a multi-value (assuming oManager and oProfile are initialised as per the top of this blog post):

if(oManager.Properties.GetPropertyByName["SomePropertyName"].IsMultiValued)

{

    // do the multi-value stuff

}

else

{

    // treat as a single value

}

I hope this helps someone out because the Microsoft documentation, at the moment, is a little sparse. 


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
posted @ Tuesday, April 24, 2007 3:28 PM | in SharePoint (MOSS) .NET/C#

Comments

Gravatar
# re: Setting MOSS User Profile properties
Posted by Dmitri
on 11/13/2007 6:40 PM
Hello Dan,

Thanks for the posting. Very interesting.

Is it possible to get User Profile inside the inline code on a Master page? And then based on that to display or hide certain fields available to that particular user.

I was able to write the inline code for other functions.

But when I try to use Microsoft.Office.Server.UserProfiles.UserProfileValueCollection on MyMaster.Master, it doesn't work.

Here is some of my code on Main.Master page:

<%@ Import Namespace="Microsoft.Office.Server.UserProfiles" %>
<%@ Import Namespace="Microsoft.Office.Server" %>
...
<script runat="server">
SPWeb web = SPContext.Current.Web;
SPUser user = web.CurrentUser;
UserProfiles.UserProfileValueCollection upvc;
ServerContext ctx = ServerContext.GetContext(HttpContext.Current);
UserProfileManager upm = new UserProfileManager(ctx);
UserProfile up = upm.GetUserProfile(user.LoginName);
upvc = up["LineofBusiness"] as UserProfileValueCollection;

ArrayList userLobs = new ArrayList();
string[] s = null;
foreach (object propValue in upvc)
{
try
{
s = propValue.ToString().Split(';');
for (int i = 0; i < s.Length; i++)
{
userLobs.Add(s[i]);
}
}
catch { }
}
</script>

Thanks a lot,
Dmitri
Gravatar
# re: Setting MOSS User Profile properties
on 5/6/2008 3:41 PM
Would this work in a Workflow?
Gravatar
# re: Setting MOSS User Profile properties
Posted by Frank Sconzo
on 7/27/2008 7:39 PM
I stumbled across your post. It was helpful to me, as I'm migrating a site from custom ASP to Sharepoint. That task includes creating about 2,000 accounts and custom profile properties.

Detecting whether the profile property is multi-valued is importatnt to me, so thanks for posting this info.

FYI, discovered a syntax correction to your line of code above; change the index lookup to a function call and make the "V" lowercase:

oManager.Properties.GetPropertyByName("SomePropertyName").IsMultivalued();

Thanks again!

Post Comment

Title *
Name *
Email
Url
Comment *  


Please add 2 and 6 and type the answer here: