• 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();

    }

  • 相关阅读:
    Win10设置多时区时钟方法技巧
    Win10技巧:使用“照片”应用剪辑视频、添加特效
    kk录像机怎么剪辑视频 kk录像机视频剪辑教程
    360快剪辑怎么使用 360快剪辑软件使用方法介绍
    WPF HyperLink链接下划线隐藏
    ORACLE 如何产生一个随机数
    电脑的开始菜单点不了 用户帐户出现在桌面上
    无法加载DLL"***.dll":找不到指定的模块
    C#调用dll提示"试图加载格式不正确的程序"原因及解决方法
    C#中与C++中的 LPWSTR(wchar_t *) 对应的类型
  • 原文地址:https://www.cnblogs.com/lambertqin/p/2987779.html
Copyright © 2020-2023  润新知