如何使用CSOM从SharePoint网站有效地获取用户(及其属性)? 下面的代码导致对服务器的多次调用(每个用户一次)。这是非常低效的。
此外,是否可以在服务器上执行过滤器?
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;
}
答案 0 :(得分:10)
重大改进
由于SharePoint CSOM支持Request Batching,因此可以使用单个请求检索所有用户配置文件,例如,而不是:
foreach (var user in siteUsers)
{
var userProfile = peopleManager.GetPropertiesFor(user.LoginName);
context.Load(userProfile);
context.ExecuteQuery();
}
用户个人资料可以检索为:
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
小改进
1)由于SharePoint CSOM支持CAML queries,因此可以在服务器端执行过滤操作,例如:
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)您还可以使用以下检查来确定指定用户是否存在用户配置文件:
var hasUserProfile = userProfile.ServerObjectIsNull != null && userProfile.ServerObjectIsNull.Value != true;
修改后的示例
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;
}
答案 1 :(得分:3)
当您在网站的特定环境中时,您可以执行以下操作:
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
}