批处理:尝试在AAD中添加多个用户异步时,userPrincipalName已存在

时间:2016-04-15 10:14:37

标签: c# azure azure-active-directory azure-ad-graph-api

我正在尝试使用AAD图添加多个用户异步这样:

IUser user1 = ...;
IUser user2 = ...;
IUser user3 = ...;
List<Task> addTasks = new List<Task>();
addTasks.Add(activeDirectoryClient.Users.AddUserAsync(user1));
addTasks.Add(activeDirectoryClient.Users.AddUserAsync(user2));
addTasks.Add(activeDirectoryClient.Users.AddUserAsync(user3));
await Task.WhenAll(addTasks);

我收到此错误消息:

  

{&#34; odata.error&#34; {&#34;代码&#34;:&#34; Request_BadRequest&#34;&#34;消息&#34; {&#34;朗&# 34;:&#34; en&#34;,&#34; value&#34;:&#34;属性userPrincipalName具有相同值的另一个对象已存在。&#34;},&#34;值&#34 ;:[{&#34;项目&#34;:&#34;的PropertyName&#34;&#34;值&#34;:&#34;的UserPrincipalName&#34;},{&#34;项目&#34; :&#34; PropertyErrorCode&#34;&#34;值&#34;:&#34; ObjectConflict&#34;}]}}

如果我使用此代码:

IUser user1 = ...;
IUser user2 = ...;
IUser user3 = ...;
List<Task> addTasks = new List<Task>();
await activeDirectoryClient.Users.AddUserAsync(user1);
await activeDirectoryClient.Users.AddUserAsync(user2);
await activeDirectoryClient.Users.AddUserAsync(user3);

这很好用。

也许我们无法同时在AAD中添加多个用户?

修改 以下是用户部分:

IUser newStudentUser = new User
{
    DisplayName = $"Etudiant de l'école {school}",
    UserPrincipalName = $"etudiant-{school}@........fr",
    AccountEnabled = true,
    MailNickname = $"Etudiant {school}",
    UsageLocation = "US",
    PasswordProfile = new PasswordProfile
    {
        Password = "......."
    }
};
IUser newTeacherUser = new User
{
    DisplayName = $"Professeur de l'école {school}",
    UserPrincipalName = $"professeur-{school}@........fr",
    AccountEnabled = true,
    MailNickname = $"Professeur {school}",
    UsageLocation = "US",
    PasswordProfile = new PasswordProfile
    {
        Password = "......."
    }
};
IUser newDirectorUser = new User
{
    DisplayName = $"Directeur de l'école {school}",
    UserPrincipalName = $"directeur-{school}@........fr",
    AccountEnabled = true,
    MailNickname = $"Directeur {school}",
    UsageLocation = "US",
    PasswordProfile = new PasswordProfile
    {
        Password = "......."
    }
};

1 个答案:

答案 0 :(得分:2)

在您的情况下,您希望批量创建多个用户。

目前,GraphClient确实支持批处理,但存在一些限制(Batch processing | Graph API concepts):

  • 单个批次最多可包含五个查询和/或更改集合。
  • 更改集最多可包含一个源对象修改,最多可包含20个添加链接和删除链接操作。更改集中的所有操作都必须位于单个源实体上。

因此,在您的情况下您无法批量创建超过5个用户

向Graph API客户端添加实体时,您可以选择使用deferredSave参数推迟执行查询。

await activeDirectoryClient.Users.AddUserAsync(user, deferredSave: true);

Graph API客户端有DataServiceContextWrapper跟踪更改。它提供了SaveChanges(Async)方法。

await activeDirectoryClient.Context.SaveChangesAsync();

调用此方法,您可以指定SaveChangesOptions

  • 批处理:所有待处理的更改都保存在一个批处理请求中。
  • BatchWithIndependentOperations :您要使用的那个,因为用户的创建应该在一个查询中。
  • ContinueOnError:通过对服务器使用多个请求来保存挂起的更改,并在发生错误后继续操作。
  • 无:通过对服务器使用多个请求来保存挂起的更改,但操作在第一次失败时停止(默认)。
  • PatchOnUpdate:
  • ReplaceOnUpdate:通过将数据源中实体的所有值替换为更新实体中的值来进行挂起更新。

现在您有足够的信息来编写代码来批量创建用户:

// Only 5 users per batch !!!!
var user1 = ...;
var user2 = ...;
var user3 = ...;
await activeDirectoryClient.Users.AddUserAsync(newStudentUser, deferredSave: true);
await activeDirectoryClient.Users.AddUserAsync(newTeacherUser, deferredSave: true);
await activeDirectoryClient.Users.AddUserAsync(newDirectorUser, deferredSave: true);

// In debug mode, you should use the SaveChangesAsync method with the default options
// Becasue the BatchWithIndependentOperations will not throw any exception even if there is a problem while creating the user.
//await activeDirectoryClient.Context.SaveChangesAsync();
await activeDirectoryClient.Context
    .SaveChangesAsync(SaveChangesOptions.BatchWithIndependentOperations);