Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get users from SharePoint via CSOM?

How can I efficiently grab users (with their properties) from a SharePoint web using CSOM? The code below results in multiple calls to the server (one for each user). It's ridiculously inefficient.

Also, is it possible to perform a Filter on the server?

    public static List<Contact> GetUsers(Uri requestUri, string Filter = "")
    {
        ClientContext context;
        var users = new List<Contact>();
        if (ClientContextUtilities.TryResolveClientContext(requestUri, out context, null))
        {
            using (context)
            {
                var web = context.Web;
                var peopleManager = new PeopleManager(context);

                context.Load(web, w => w.Title, w => w.Description, w => w.SiteUsers);
                var siteUsers = web.SiteUsers;
                context.ExecuteQuery();

                foreach (var user in siteUsers)
                    if (user.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.User)
                        if (user.Title.ToLower().Contains(Filter.ToLower()) && !users.Any(x => x.FullName == user.Title))
                        {
                            var userProfile = peopleManager.GetPropertiesFor(user.LoginName);
                            context.Load(userProfile);
                            context.ExecuteQuery();

                            var contact = new Contact() { FullName = user.Title, EmailAddress = user.Email };
                            if (userProfile.IsPropertyAvailable("Title"))
                                contact.Position = userProfile.Title;
                            if (userProfile.IsPropertyAvailable("UserProfileProperties") && userProfile.UserProfileProperties.ContainsKey("WorkPhone"))
                                contact.PhoneNumber = userProfile.UserProfileProperties["WorkPhone"];
                            users.Add(contact);
                        }
            }
        }
        return users;
    }
like image 440
Matt Fitzmaurice Avatar asked Apr 15 '15 11:04

Matt Fitzmaurice


People also ask

How do I get a list of users in SharePoint?

The SharePoint User Information List can be accessed via the browser by navigating to “/_catalogs/users/simple. aspx” from your site. You can see a screenshot of SharePoint Online user information list for on of my SharePoint Online site.

How does Csom get SharePoint List data?

You can get the SharePoint Client Object Model URLs from the Microsoft site or can download the package from NuGet package. Open Visual Studio and create a new console application. Add CSOM (Client Side Object Model) Library from NuGet package. Replace the code in Program.


2 Answers

Major improvements

Since SharePoint CSOM supports Request Batching all the user profiles could be retrieved using a single request, for example instead of:

foreach (var user in siteUsers)
{
   var userProfile = peopleManager.GetPropertiesFor(user.LoginName);
   context.Load(userProfile);
   context.ExecuteQuery();
}

user profiles could be retrieved as:

var userProfilesResult = new List<PersonProperties>(); //for storing user profiles
foreach (var user in siteUsers)
{
   var userProfile = peopleManager.GetPropertiesFor(user.LoginName);
   context.Load(userProfile);
   userProfilesResult.Add(userProfile);
}
context.ExecuteQuery();  //submit a single request 

Minor improvements

1)Since SharePoint CSOM supports CAML queries, the filtering operation could be performed on the server side, for example:

var siteUsers = from user in web.SiteUsers
                    where user.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.User
                    select user;
var usersResult = context.LoadQuery(siteUsers);
context.ExecuteQuery();

2)You could also use the following checking to determine whether user profile exist for a specified user:

var hasUserProfile = userProfile.ServerObjectIsNull != null && userProfile.ServerObjectIsNull.Value != true;

Modified example

public static List<Contact> GetUsers(Uri requestUri, ICredentials credentials, string filter = "")
{
        ClientContext context;
        var users = new List<Contact>();
        if (ClientContextUtilities.TryResolveClientContext(requestUri, out context, credentials))
        {
            var userProfilesResult = new List<PersonProperties>();
            using (context)
            {
                var web = context.Web;
                var peopleManager = new PeopleManager(context);


                var siteUsers = from user in web.SiteUsers
                    where user.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.User
                    select user;
                var usersResult = context.LoadQuery(siteUsers);
                context.ExecuteQuery();

                foreach (var user in usersResult)
                {
                    if (user.Title.ToLower().Contains(filter.ToLower()) && !users.Any(x => x.FullName == user.Title))
                    {
                        var userProfile = peopleManager.GetPropertiesFor(user.LoginName);
                        context.Load(userProfile);
                        userProfilesResult.Add(userProfile);
                    }
                }
                context.ExecuteQuery();


                var result = from userProfile in userProfilesResult 
                             where userProfile.ServerObjectIsNull != null && userProfile.ServerObjectIsNull.Value != true
                        select new Contact() {
                            FullName = userProfile.Title,
                            EmailAddress = userProfile.Email,
                            Position = userProfile.IsPropertyAvailable("Title") ? userProfile.Title : string.Empty,
                            PhoneNumber = userProfile.IsPropertyAvailable("UserProfileProperties") && userProfile.UserProfileProperties.ContainsKey("WorkPhone") ? userProfile.UserProfileProperties["WorkPhone"] : string.Empty
                        };
                users = result.ToList();
            }
        }
        return users;
 }
like image 152
Vadim Gremyachev Avatar answered Sep 28 '22 02:09

Vadim Gremyachev


When you are in a specific context of a website you can do followings:

using (var ctx = new ClientContext("http://theWebsite"))
{
    var list = ctx.Web.SiteUserInfoList;
    var users = list.GetItems(new CamlQuery());
    ctx.Load(users);
    ctx.ExecuteQuery();

    // do what you want with the users
}
like image 24
Emaborsa Avatar answered Sep 28 '22 00:09

Emaborsa