【问题标题】:MS Graph SDK How to Add/Update a Schema Extension property to a User objectMS Graph SDK 如何将架构扩展属性添加/更新到用户对象
【发布时间】:2021-03-28 18:23:08
【问题描述】:

我很难找到有关如何在 Azure AD 中针对用户添加架构扩展值的任何代码示例。

到目前为止,我已经成功创建了自己的架构扩展,标记为“用户”TargetType,并将状态更新为“可用”。这一切都是通过 MS Graph SDK 实现的

下面是我在应用中创建并列出的扩展的屏幕截图:

这个扩展非常基本,只有一个名为“name”的属性被设置为类型字符串。

我现在想要执行以下功能:

  • 创建一个新用户并使用 my 新创建的架构扩展,即该用户将架构扩展属性“名称”设置为我选择的字符串值。
  • 为现有用户更新架构扩展属性的值。
  • 对我的租户中所有在此架构扩展中设置了特定值的用户运行过滤搜索。

MS Docs 给出的唯一示例是使用 MS Graph API,不是我在我的应用程序中使用的 SDK。此外,他们给出的唯一示例是在创建新组时添加架构扩展。

https://docs.microsoft.com/en-us/graph/extensibility-schema-groups

在他们的笔记中,MS 说如下: 注意:本主题向您展示如何在组资源上创建和读取架构扩展值(步骤 3-5)。管理单元、设备、事件、消息、组织、帖子和用户资源类型也支持相同的方法。您可以对任何这些资源执行类似于本文中请求示例的操作。

谁能告诉我从哪里获得代码示例,该示例允许我使用此扩展程序创建/更新用户,以及对我的租户中的所有用户使用过滤搜索,这些用户在他们的个人资料中为此特定扩展程序设置了特定值?

更新:结合 Allen Wu 在下面的答案中的讨论,我已经实现了他的代码示例,在创建新用户时将模式扩展添加为“AdditionalData”。我还没有设法让它工作,因为我收到一条错误消息“Code: BadRequest\r\nMessage: Unsupported Schema Extension Property value of type String\r\nInner error:\r\n\tAdditionalData:\r\ n\tdate: 2021-03-31T18:51:32\r\n\trequest-id"

使用架构扩展创建新用户的代码示例:

var user = new User();
user.UserPrincipalName = TenantUser.UserPrincipalName + "@" + Domain; // * Required
//user.UserPrincipalName = TenantUser.UserPrincipalName; // * Required
user.DisplayName = TenantUser.GivenName + " " + TenantUser.Surname; // * Required
user.GivenName = TenantUser.GivenName; // * Required
user.Surname = TenantUser.Surname; // * Required

if (TenantUser.Password != null)
{
   if (TenantUser.Password != TenantUser.ConfirmPassword)
   {
       ModelState.AddModelError(string.Empty, "\n Passwords do not match!");
       return Page();
   }
   else
   {
       user.PasswordProfile = new PasswordProfile
       {
           Password = TenantUser.ConfirmPassword,
       };
    }
}

user.AccountEnabled = AccountEnabled;
user.JobTitle = TenantUser.JobTitle;
user.Department = TenantUser.Department;
user.EmployeeId = TenantUser.EmployeeId;
user.OfficeLocation = TenantUser.OfficeLocation;
user.CompanyName = TenantUser.CompanyName;
user.StreetAddress = TenantUser.StreetAddress;
user.State = TenantUser.State;
user.City = TenantUser.City;
user.PostalCode = TenantUser.PostalCode;
user.Country = TenantUser.Country;
user.MobilePhone = TenantUser.MobilePhone; // * Required

if (BusinessPhone != null)
{
    user.BusinessPhones = new List<String>()
    {
         BusinessPhone // see public string
    };
}

user.Mail = TenantUser.Mail; // * Required
user.MailNickname = TenantUser.MailNickname;
user.AdditionalData = new Dictionary<string, object>()
{
    {"ext7bxc3e0l_appRoleTemplate", "{\"name\":\"Template1\"}"}             
};

try
{
     await graphClient.Users
     .Request()
     .AddAsync(user);

      LogData = "New User with name [" + UserFullName + "] created by user with forename [" + currentUser.Forename + "] surname [" + currentUser.Surname + "] Succesfully";
      // See helper method at bottom.
      logExtension.WriteLogEvent<EditModel>("Information", "Users", "Created", UserFullName, currentUser.Id, currentUser.Username, currentUser.Forename, currentUser.Surname, LogData, null, _scopeFactory);
}
catch (ServiceException ex)
{
    // Graph service exception friendly message
    var errorMessage = ex.Error.Message;
    LogData = " Error creating the User. Microsoft Graph API encountered a Service Exception with message [" + errorMessage + "]'";
    logExtension.WriteLogEvent<EditModel>("Error", "User", "Created", $"User with Id = {currentUser.Id}", currentUser.Id, currentUser.Username, currentUser.Forename, currentUser.Surname, LogData, null, _scopeFactory);
    ModelState.AddModelError(string.Empty, errorMessage + " Error creating the User.\n Please check the system logs for details");
    return Page();
}

【问题讨论】:

    标签: c# azure-active-directory microsoft-graph-sdks


    【解决方案1】:

    我创建了一个架构扩展:

    {
        "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions/$entity",
        "id": "ext253rtfdu_name",
        "description": "user name extensions",
        "targetTypes": [
            "User"
        ],
        "status": "InDevelopment",
        "properties": [
            {
                "name": "userId",
                "type": "String"
            },
            {
                "name": "userName",
                "type": "String"
            },
            {
                "name": "userType",
                "type": "String"
            }
        ]
    }
    

    使用ext253rtfdu_name 架构扩展创建用户:

    GraphServiceClient graphClient = new GraphServiceClient(authProvider);
    
    string extStr = "{\"userId\":\"321\",\"userName\":\"Adele test02\",\"userType\":\"member\"}";
    
    JObject jsonObj = JObject.Parse(extStr);
    
    var user = new User
    {
        AccountEnabled = true,
        DisplayName = "Adele test01",
        MailNickname = "AdeleVtest01",
        UserPrincipalName = "AdeleVtest01@contoso.onmicrosoft.com",
        PasswordProfile = new PasswordProfile
        {
            ForceChangePasswordNextSignIn = true,
            Password = "password-value"
        },
        AdditionalData = new Dictionary<string, object>()
        {
            {"ext253rtfdu_name", extStr}
        }
    };
    
    await graphClient.Users
        .Request()
        .AddAsync(user);
    

    更新用户:

    GraphServiceClient graphClient = new GraphServiceClient(authProvider);
    
    string extStr = "{\"userId\":\"456\",\"userName\":\"Adele test02\",\"userType\":\"member\"}";
    
    JObject jsonObj = JObject.Parse(extStr);
    
    var user = new User
    {
        AdditionalData = new Dictionary<string, object>()
        {
            {"ext253rtfdu_name", jsonObj}
        }
    };
    
    await graphClient.Users["AdeleVtest01@contoso.onmicrosoft.com"]
        .Request()
        .UpdateAsync(user);
    

    我尝试使用https://graph.microsoft.com/v1.0/users?$filter=ext253rtfdu_name/userId eq ‘456’&amp;$select=displayName,id,userPrincipalName,ext253rtfdu_name 过滤扩展以获取用户,但它显示Invalid filter clause。不过按照Filtering on schema extension properties known issues的说法应该是支持的。

    我不明白这个过滤器会发生什么,但代码示例应该是:

    var res = await _graphClient.Users.Request()
        .Filter($"ext253rtfdu_name/userId eq '456'").GetAsync()
    

    similar post 供您参考。

    你可以试试看。

    【讨论】:

    • 嗨,艾伦,非常感谢您抽出宝贵的时间,我将立即着手处理,需要几个小时才能将其添加到我现有的代码中,但肯定会让您知道结果
    • 我尝试在使用 {"ext7bxc3e0l_appRoleTemplate", "{\"name\":\"Template1\"}"} 更新用户时添加架构,但我收到一条错误消息“不支持的架构字符串类型的扩展属性值”这很奇怪,因为我只有一个模式属性设置为字符串类型。
    • @OJB1 name 是一个字符串?您似乎为name 设置了一个不受支持的值(Template1?)。请分享您如何定义ext7bxc3e0l_appRoleTemplate
    • @OJB1 你检查我的评论了吗?有更新吗?
    • 嗨,Allen,Template1 只是我用于属性值“名称”的字符串的一个示例。我创建的模式扩展与您在上面给出的示例中一样,除了我只有一个名为“name”的属性并且值类型设置为字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 2020-07-08
    相关资源
    最近更新 更多