zoukankan      html  css  js  c++  java
  • SharePoint客户端开发:增加用户信息到用户信息列表

    用户信息列表(User Information List),这个隐藏的SharePoint列表,主要用来储存一些用户Profile的基本数据。这个列表不能使用普通的方式去添加或者删除数据。

    首先,为什么要在这个列表中增加数据?

    这个列表是由SharePoint进行管理的,在使用PeoplePicker控件的时候,点时候就会自动把用户添加进用户信息列表。对于列表中的用户类型的字段来说,这个会利用ID关联到用户信息列表。

    我碰到过2个典型场景:

    1. 实际用户操作中,对于批量数据导入的时候,一般使用的是Datasheet View,通过Excel导入。如果张三从来没有访问过网站,导入的时候有张三这个人,这个时候Datasheet View就会报错。无法保存。
    2. 开发跨站点集的数据迁移同步,张三是A网站用户,却不是B网站用户,需要把涉及到张三的数据迁移到B网站。

    对于第一个场景,可以让用户随便找个PeoplePicker控件,输入缺失的人信息,然后点,就可以补充回来。

    对于开发者,一般情况下,服务端开发,可以用SPWeb.EnsureUser来添加用户到这个列表中。

    对应客户端开发:

    大多数情况下,前面一种Client OM可以满足需要了。

    不过Web.EnsureUser有个问题就是一次只能添加一个用户,并且这个是一个完整的服务请求,大数据量的情况下效率很成问题。

    为了解决这个问题,需要利用到多线程。

    这里我有一段我实际使用的代码作为参考:

    实际使用多线程的过程中,我遇到了一个问题,参考了这篇讨论中给出的方法:Workaround for the WaitHandle.WaitAll 64 handle limit?

    UserInfoList targetList = new UserInfoList(Parameters.TargetUrl, Parameters.ListNames.UserInformation);

    IList<User> resolvedUsers = new List<User>();

    logger.Info("Sync User Information from {0} to {1} started...", Parameters.SourceUrl, Parameters.TargetUrl);

    int threadCount = 0;

    ManualResetEvent finished = new ManualResetEvent(false);

    foreach (var u in Users)

    {

    Interlocked.Increment(ref threadCount);

    ThreadPool.QueueUserWorkItem(delegate

    {

    try

    {

    logger.Info("Resolving user in target web site:", u.SipAddress, u.Account);

    if (!String.IsNullOrEmpty(u.Account) && targetList.GetUserInfoByAccount(u.Account) == null)

    {

    User targetUser = targetList.Web.EnsureUser(u.Account);

    targetList.Context.Load(targetUser);

    targetList.Context.ExecuteQuery();

    resolvedUsers.Add(targetUser);

    logger.Info("User resolved:", u.SipAddress, u.Account);

    }

    else

    {

    logger.Info("User exists or user is not valid:", u.SipAddress, u.Account);

    }

    }

    catch (Exception)

    {

    logger.Info("Cannot update user information for {0} ({1})", u.SipAddress, u.Account);

    }

    finally

    {

    if (Interlocked.Decrement(ref threadCount) == 0)

    {

    finished.Set();

    }

    }

    });

    }

    finished.WaitOne();

    logger.Info("Sync User Information from {0} to {1} completed...", Parameters.SourceUrl, Parameters.TargetUrl);

    如果不熟悉多线程,为了提高性能,只能用传统的Web Service来做,用People.ResolvePrincipals方法,因为这个方法的参数允许数组。在一次HTTP请求中可以传递多个用户,大大节约了HTTP往返时间。

    同样,我也有一段我实际使用的代码作为参考:

    值得注意的问题时,使用的时候,不能一次性的添加过多的用户,这样会导致Web Service超时失败。

    public UserInfo[] EnsureUsers(string[] accounts, int batch = 200, string url = default(string))

    {

    if (url == default(string)) { url = WebUrl; }

    logger.Info("Ensuring user information in {0} web site", url);

    List<PrincipalInfo> pi = new List<PrincipalInfo>();

    for (int i = 0; i < Math.Ceiling((double)accounts.Length / batch); i++)

    {

    string[] batchAccounts = accounts.Skip(i * batch).Take(batch).ToArray();

    People peopleService = new People();

    peopleService.Url = url + "/_vti_bin/people.asmx";

    peopleService.Credentials = System.Net.CredentialCache.DefaultCredentials;

    pi.AddRange(peopleService.ResolvePrincipals(batchAccounts, SPPrincipalType.User, true));

    }

    List<UserInfo> users = Convert(pi);

    logger.Info("Found {0} user information items and updated to user information store", users.Count);

    return users.ToArray();

    }

  • 相关阅读:
    图像检索(image retrieval)- 11
    图像检索(image retrieval)- 10相关
    Mock.js简易教程,脱离后端独立开发,实现增删改查功能
    Azure Monitor (3) 对虚拟机磁盘设置自定义监控
    Azure Monitor (1) 概述
    Azure SQL Managed Instance (2) 备份SQL MI
    Azure Virtual Network (17) Private Link演示
    Azure Virtual Network (16) Private Link
    Azure Virtual Network (15) Service Endpoint演示
    Azure Virtual Network (14) Service Endpoint服务终结点
  • 原文地址:https://www.cnblogs.com/lambertqin/p/2987779.html
Copyright © 2011-2022 走看看