3

I am trying to retrieve a random number of users from the UserProfileManager.

But I am encountering errors when deploying to the live servers. I can't seem to see what is causing the error. My code is below:

for (int i = 0; i < NumberOfUserLimit; i++)
            {
                UserProfile up = profileManager.GetUserProfile(random.Next(1, NumberOfUserLimit));

                if (up["FirstName"] != null && up["FirstName"].Value != null && !String.IsNullOrEmpty(up["FirstName"].Value.ToString()))
                {
                    DataRow drUserProfile;

                    drUserProfile = dtUserProfile.NewRow();

                    drUserProfile["DisplayName"] = up.DisplayName;
                    drUserProfile["FirstName"] = up["FirstName"].Value;
                    drUserProfile["LastName"] = up["LastName"].Value;
                    drUserProfile["Department"] = up["Department"].Value;
                    drUserProfile["Location"] = up["SPS-Location"].Value;
                    drUserProfile["HireDate"] = up["SPS-HireDate"].Value;
                    drUserProfile["ContactNumber"] = up["Office"].Value;

                    if (up["PictureURL"] != null && up["PictureURL"].Value != null && !String.IsNullOrEmpty(up["PictureURL"].Value.ToString()))
                    {
                        string cleanAccountName = up["AccountName"].Value.ToString().Replace(@"\", "_");
                        string pictureUrl = String.Format("https://my.someintranet.com/User Photos/Profile Pictures/{0}_MThumb.jpg", cleanAccountName);

                        drUserProfile["Image"] = pictureUrl;
                    }
                    else
                    {
                        drUserProfile["Image"] = "~/_layouts/images/O14_person_placeHolder_96.png";
                    }

                    drUserProfile["MySiteUrl"] = up.PublicUrl;

                    dtUserProfile.Rows.Add(drUserProfile);
                }
            }

My code works when I apply a simple foreach to my code above instead of the "for loop":

    foreach (UserProfile up in profileManager)

Which proves I can return userprofiles.

Any help is appreciated.

R100
  • 471
  • 1
  • 10
  • 25
  • Why *not* use a foreach? Another related question is http://stackoverflow.com/questions/3627980/getting-a-random-user-using-userprofilemanager – Dennis G Feb 23 '11 at 19:39
  • I could use a foreach loop because I wanted to get a random collection of users based on the number of users I wanted to return. – R100 Feb 23 '11 at 21:29

2 Answers2

2
profileManager.GetUserProfile(long recordId) 

expects a recordId from userprofile table. It is not an index, so you cannot use "random".

If you want to check RecordId, you can take a look at SQL tables of ProfileDB. Table "UserProfile_Full" has MasterRecordId column. Your parameter in GetUserProfile has to match of the user profile's MasterRecordId.

you can use the following code to get your random profiles:

IEnumerator profiles = profileManager.GetEnumerator(); 
int index = new Random().Next(1, 100); 
while (index >= 0 && profiles.MoveNext()) 
   index--; 

UserProfile currentProfile = (UserProfile)profiles.Current
Dmitry
  • 589
  • 4
  • 5
  • Won't this give profiles from within same 100 profiles every time. – ukhardy Feb 23 '11 at 21:11
  • @ukhardy Yes this is what I want. I will replace the "100" value to a custom web part property to control how many profiles I want to return. So all I need to do is populate my datatable within the while statement. I shall give that a go tomorrow. Thanks Dmitry. – R100 Feb 23 '11 at 21:19
  • @Dmitry I just got a quick question. Why do you decrement the index variable in the while loop? – R100 Feb 23 '11 at 21:27
  • Basically you need to perform (profiles.MoveNext()) N-number of times. So "index" being equals {random} would be decreasing each time we do (profiles.MoveNext()). Let me know if you have any additional questions. – Dmitry Feb 23 '11 at 23:18
  • @Dmitry That looks like that solved my error. But I think @ukhardy was right. The same profiles are getting returned...Well the first 10-20. After that its random. – R100 Feb 24 '11 at 12:52
  • 1
    @R100 Move "Random random = new Random() to your class constructor. Then work with random.Next(...) it should help – Dmitry Feb 24 '11 at 19:29
  • @Dmitry So I would change the code to the following: int index = new Random().Next(1, 100); while (index >= 0 && profiles.MoveNext()) { Random random = new Random(); random.Next(1, index--); UserProfile currentProfile = (UserProfile)profiles.Current ... } – R100 Feb 24 '11 at 22:29
  • @R100: It is hard to understand code in the comments. I will post code as another reply... – Dmitry Feb 24 '11 at 23:31
1

Code that handles Random better

public class TestClass
{
   private random = new Random();
   private long totalNumberOfProfiles;   //ProfileManager.Count not always returns count correctly

   public TestClass()
   {
      //this does not have to be in constructor but point is to have it cached (reasonably)
      IEnumerator profiles = profileManager.GetEnumerator(); 
      long counter = 0;
      while (profiles.MoveNext())
         counter++;
      this.totalNumberOfProfiles = counter;
   }


   public fillInDataSet()
   {
      //something is here...
      IEnumerator profiles = profileManager.GetEnumerator(); 
      int index = random.Next(1, totalNumberOfProfiles); 
      while (index >= 0 && profiles.MoveNext()) 
        index--; 

      UserProfile currentProfile = (UserProfile)profiles.Current

      //something is here...

   }
}
Dmitry
  • 589
  • 4
  • 5