Wednesday, August 08, 2007

MOSS GetUserProfileByIndex(int index) unexpected behaviour

We are trying to get a list of user profiles from MOSS using the UserProfile WebService. We were assuming that as each user gets created the index is incremented by one, so we could do a for next loop to get them all, however this gives errors.

Here is the solution from Microsoft:
------------------
We are using the GetUserProfileByIndex(int index) method in a for loop looping from index = 0 to index = (GetUserProfileCount() -1) value.

This is however not the right approach.

While the profiles are created and deleted the profile list does not keep continuous indexing (e.g. if you have 10 profiles indexed from 0 to 9 and then you delete profiles (5) and (6) there will be a gap - indexes 5 and 6 will not be used. Adding new profiles to the list will not insert them into the gap, but will append them to the end of the list. So, if after deleting profiles (5) and (6) you add 3 new profiles the indexes will be as follows {0, 1, 2, 3, 4, 7, 8, 9, 10, 11, 12}). If you would run a for loop for this list for the indexes 0 to (GetUserProfileCount() -1), so 0 to 10, you would never get the profiles (11) and (12) returned and you would get the profile (7) returned 3 times (if a profile under a given index is missing the function returns the next available one).

The right approach is to use the NextValue field of the GetUserProfileByIndexResult object returned by the GetUserProfileByIndex(int index) function. This field contains a string value indicating the next valid index in the profile list. The string value needs to be converted into an integer and then used in the next call of the GetUserProfileByIndex(int index) function as the index. The fist value in the list can be obtained by using an index <= 0.
The pseudo code for extracting all the user profiles:

p = GetUserProfileByIndex(-1); // gets the first profile on the list
While (p.UserProfile != null)
{
// do what you want with the User Profile
.....
.....
.....
int nextValue = ConvertToInteger(p.NextValue);
p = GetUserProfileByIndex(nextValue);
}

No comments: