views:

725

answers:

3

Is there a way to search profiles in MOSS from the object model? I need to search for profiles that have a certain value set on their profile and then perform some action for them.

I need to write some c# code that can search the profiles database and return the matching profiles. Basically,

List of Profiles = Select Profiles From Profile Store Where Profile Property Value = SomeValue

I'm trying to avoid the following:

 private IEnumerable<UserProfile> SearchProfiles(string value) {
        ServerContext serverContext = ServerContext.GetContext(SPContext.Current.Site);
        UserProfileManager profileManager = new UserProfileManager(serverContext);
        foreach (UserProfile profile in profileManager) {
            if ((string)profile["MyProp"].Value == value) {
                yield return profile;
            }
        }
    }
+1  A: 

This is possible using the FullTextSqlQuery class:

FullTextSqlQuery q = new FullTextSqlQuery(ServerContext.Current);
q.ResultTypes = ResultType.RelevantResults;
q.QueryText = "SELECT UserName, Email, PreferredName FROM SCOPE() WHERE \"scope\" = 'People' AND Department = 'IT'";

ResultTableCollection tables = q.Execute();
ResultTable results = tables[ResultType.RelevantResults];

This class allows you to query a specific scope (i.e. people) and filter them based on properties using the WHERE clause, which looks basically the same as a regular Sql Query.

To be able to search and filter on (custom) user profile properties, the profile property needs to have a mapping in the Shared Service Provider's metadata settings. Most out of the box user profile properties already have these, custom properties you have to add yourself.

More info on managed properties here.

Colin
A: 

I get 403:Unauthorized when I access the site and "Access Denied: Only an administrator may enumerate through all user profiles" when debug.

I'm using "foreach (UserProfile profile in profileManager)" and it is running with elevated privileges.

My code is:

    protected override void Render(HtmlTextWriter writer)
    {
        SPSecurity.RunWithElevatedPrivileges(
        delegate()
        {
            try
            {
                //SPSite mySite = SPControl.GetContextSite(Context);
                //SPWeb myWeb = SPControl.GetContextWeb(Context);
                ServerContext context = ServerContext.GetContext(SPContext.Current.Site);
                UserProfileManager myProfileManager = new UserProfileManager(context);
                //string currentUser = SPContext.Current.Web.CurrentUser.LoginName;
                //UserProfile myProfile = myProfileManager.GetUserProfile(currentUser);

                foreach (UserProfile myProfile in myProfileManager)
                {
                    if ((string)myProfile["EmployeeID"].Value == "7708")

                    lblFirstName.Text = myProfile[PropertyConstants.FirstName].Value.ToString();
                    lblLastName.Text = myProfile[PropertyConstants.LastName].Value.ToString();
                    lblMgrName.Text = myProfile[PropertyConstants.Manager].Value.ToString();
                }
            }
            catch (UserNotFoundException ex)
            {
                lblMessage.Text = ex.ToString();
            }
        });
        writer.Write("<Table class='ms-formtable' style='margin-top: 8px;' border=0 cellpadding=0 cellspacing=0 width=100%>");

        writer.Write("<TR><TD nowrap='true' valign='top' width='190px' class='ms-formlabel'><H3 class='ms-standardheader'><nobr>FirstName</nobr></H3></TD><TD valign='top' class='ms-formbody' width='400px'><span dir='none'>");
        lblFirstName.RenderControl(writer);
        writer.Write("<br></span></TD></TR>");

        writer.Write("<TR><TD nowrap='true' valign='top' width='190px' class='ms-formlabel'><H3 class='ms-standardheader'><nobr>Lastname</nobr></H3></TD><TD valign='top' class='ms-formbody' width='400px'><span dir='none'>");
        lblLastName.RenderControl(writer);
        writer.Write("<br></span></TD></TR>");

        writer.Write("<TR><TD nowrap='true' valign='top' width='190px' class='ms-formlabel'><H3 class='ms-standardheader'><nobr>Manager</nobr></H3></TD><TD valign='top' class='ms-formbody' width='400px'><span dir='none'>");
        lblMgrName.RenderControl(writer);
        writer.Write("<br></span></TD></TR>");

        writer.Write("</Table>");

}

Am I doing something wrong?

Any help is much appreciated.

Tarun
A: 

Two things: 1) when running with elevated privileges we need to create a new SPSite object within the call and load the security context from there. DO NOT use the context obtained using SPContext.Current.Site.

Hence:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
 using (SPSite site = new SPSite("<your site url>"))

 {

  ServerContext context = ServerContext.GetContext(site);

  UserProfileManager profileManager = new

  UserProfileManager(context);

  foreach (UserProfile profile in profileManager)
{
// your code
        }

 }


}

2) make sure that the app pool account has appropriate user permissions in SSP. i.e. (use personal features, manage user profiles)

Himani

related questions