User subtypes are one of the many new and nice things in SharePoint 2010.
The other day I was editing user profiles and changed the subtype for this profile in code. After changing the user subtype Commit() was called and I thought I was done.
But then it just started, because the user profile wasn’t updated at all. No exception, no message at all, just the old user subtype.
The used code:
ProfileSubtypeManager psubm = ProfileSubtypeManager.Get(context); ProfileSubtype newSubtype = psubm.GetProfileSubtype(newSubtypeName); currentUserProfile.ProfileSubtype = newSubtype; currentUserProfile.Commit();
Changing the user subtype in the UI really updated the setting, so it was time to debug the SharePoint UserProfiles assembly.
The short version of what the debugging session(s) told me:
A UserProfileUpdateWrapper was created with the following xml
<?xml version="1.0" encoding="utf-16"?> <MSPROFILE> <PROFILE ProfileName="UserProfile"> <USER NewUser="0" NTAccount="account" UserID="3db01e67-abb0-4946-8fa8-85943768cb79">
The next step is iterating through the user profile fields to check if the value ‘IsDirty’ aka the value has been changed. This is the only trigger to actually update a user profile.
When adjusting the user subtype from the UI a few properties are updated, even when they’re not changed. The final XML looks like the following:
<?xml version="1.0" encoding="utf-16"?> <MSPROFILE> <PROFILE ProfileName="UserProfile"> <USER NewUser="0" NTAccount="account" UserID="3db01e67-abb0-4946-8fa8-85943768cb79"> <PROPERTY PropertyName="Assistant" Privacy="1" PropertyValue="" /> <PROPERTY PropertyName="PictureURL" Privacy="1" PropertyValue="" /> <PROPERTY PropertyName="SPS-TimeZone" Privacy="1" PropertyValue="" /> </USER> </PROFILE> </MSPROFILE>
and a real update of the user profile occurred.
To make the update work from code appearently another property has to be updated together with the change of subtype. After a test with an update of a random property, the user subtype was updated too.
Summary
Changing only the user subtype from code, does trigger the Commit() method, but doesn’t call the update profile, because no user profile property was changed. Use a dummy property to update every time the user subtype has changed.
Very good advice! I have been previously hunting for something similar to this for a long time now. Cheers!