如何检查特定ID的SharePoint用户是否存在?
嘿,这个问题我太有共鸣了!靠捕获异常跳过不存在的用户确实效率拉胯,尤其是处理大量旧数据的时候,频繁的异常处理会拖慢整个流程。下面给你两种更高效的解决方案:
1. 批量查询用户信息列表(最优解)
SharePoint的**用户信息列表(User Information List)**存储了所有曾经在站点中存在过的用户记录,包括已删除的用户(会标记IsDeleted属性)。我们可以通过CamL查询一次性筛选出存在且未被删除的用户,避免逐个请求的开销,效率提升非常明显。
示例代码:
private List<User> GetValidUsers(List<int> userIds, ClientContext clientContext) { var validUsers = new List<User>(); var userInfoList = clientContext.Web.SiteUserInfoList; // 构建CamL查询,筛选出目标ID中未被删除的用户 var camlQuery = new CamlQuery(); camlQuery.ViewXml = $@" <View> <Query> <Where> <And> <In> <FieldRef Name='ID' /> <Values> {string.Join("", userIds.Select(id => $"<Value Type='Integer'>{id}</Value>"))} </Values> </In> <Eq> <FieldRef Name='IsDeleted' /> <Value Type='Boolean'>False</Value> </Eq> </And> </Where> </Query> <ViewFields> <FieldRef Name='ID' /> <FieldRef Name='EMail' /> </ViewFields> </View>"; var listItems = userInfoList.GetItems(camlQuery); clientContext.Load(listItems, items => items.Include(item => item["ID"], item => item["EMail"])); clientContext.ExecuteQuery(); // 批量加载有效用户的详细信息 var validUserIds = listItems.Select(item => (int)item["ID"]).ToList(); foreach (var id in validUserIds) { var user = clientContext.Web.GetUserById(id); clientContext.Load(user, u => u.Email); validUsers.Add(user); } clientContext.ExecuteQuery(); return validUsers; }
这种方法只需要2次请求(一次查询用户列表,一次加载有效用户信息),而不是N次逐个请求,处理大量数据时优势特别突出。
2. 封装TryGetUserById扩展方法(适合逐个处理场景)
如果业务逻辑必须保持逐个处理的模式,可以自己封装一个扩展方法,通过轻量查询检查用户是否存在,避免抛出不必要的异常:
public static class ClientContextExtensions { public static bool TryGetUserById(this Web web, int userId, out User user) { user = null; var clientContext = web.Context; try { // 只加载用户ID属性,请求量极小 user = web.GetUserById(userId); clientContext.Load(user, u => u.Id); clientContext.ExecuteQuery(); return true; } catch (ServerException ex) { // 仅捕获"用户不存在"的特定异常 if (ex.Message.Contains("User cannot be found")) { return false; } // 其他异常正常抛出 throw; } } }
使用示例:
private void GetUsrInfo(FieldUserValue user, ClientContext clientContext) { int id = user.LookupId; Web web = clientContext.Web; if (web.TryGetUserById(id, out User spuser)) { clientContext.Load(spuser, u => u.Email); clientContext.ExecuteQuery(); Mail = spuser.Email; } else { // 处理用户不存在的情况,比如跳过或标记 Mail = null; } }
这个方法虽然还是逐个请求,但因为只加载Id属性,请求量比加载完整用户信息小很多,异常触发的频率也更低。
总结
优先推荐第一种批量查询的方式,尤其是处理大量用户的时候,能大幅减少请求次数和开销。如果业务逻辑必须逐个处理,第二种扩展方法也能比原来的异常捕获方式更高效。
内容的提问来源于stack exchange,提问作者Ole Albers
相关产品推荐
相关产品推荐

