通过GRAPH更新Azure AD中的用户时出现Json序列化错误

时间:2016-07-12 06:01:33

标签: c# json.net microsoft-graph azure-ad-graph-api

我使用Microsoft.Graph库here更新Azure AD中的用户。这对某些用户有效,但对其他用户无效。我的代码如下所示:

public async Task<User> UpdateUser(AdUser adUser)
{
    var graphServiceClient = new GraphServiceClient(_azureAuthenticationProvider);

    var user = await GetUser(adUser.UserPrincipalName);

    user.GivenName = adUser.GivenName;
    user.Surname = adUser.LastName;
    user.DisplayName = adUser.DisplayName;
    user.Department = adUser.Department;
    user.AccountEnabled = adUser.AccountEnabled;

    await graphServiceClient.Users[user.UserPrincipalName].Request().UpdateAsync(user);
    await UpdateUserGroups(adUser);

    return await GetUser(adUser.UserPrincipalName);
}

AdUser类非常基础,只包含要更新的属性:

public class AdUser
{
    public string UserPrincipalName { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string GivenName { get; set; }
    public string LastName { get; set; }
    public string DisplayName { get; set; }
    public string Department { get; set; }
    public List<string> OldGroups { get; set; }
    public List<string> OldRoles { get; set; }
    public List<string> NewGroups { get; set; }
    public List<string> NewRoles { get; set; }
    public bool AccountEnabled { get; set; }
    public bool ForceChangePasswordNextSignIn { get; set; }
}

对于要更新的​​前三个用户,这很好用。在第四个用户上,我得到一个带有消息的通用AggregateException,&#34;类型的异常&#39; Microsoft.Graph.ServiceException&#39;被扔了。&#34;

Fid up Fiddler显示失败的请求:

{
  "error": {
    "code": "InternalServerError",
    "message": "Can not add property department to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.",
    "innerError": {
      "request-id": "b82c4098-6031-40c4-ac6a-4f43746e7b48",
      "date": "2016-07-12T05:55:08"
    }
  }
}

如果我单步执行代码,我可以看到此行发生错误:

await graphServiceClient.Users[user.UserPrincipalName].Request().UpdateAsync(user);

这始终发生在同一个用户身上。有什么想法吗?

感谢!!!

更新1: 为了完整起见,我的GetUser方法如下所示:

public const string AdUserFields = "UserPrincipalName,DisplayName,GivenName,Surname,Department,MemberOf,AccountEnabled";

public async Task<User> GetUser(string userPrincipalName, string fields = AdUserFields)
{
    var graphServiceClient = new GraphServiceClient(_azureAuthenticationProvider);

    var user = await graphServiceClient.Users[userPrincipalName].Request().Select(fields).GetAsync();

    return user;
}

更新2: 请求和响应看起来像这样。请注意,我没有构建JSON,SDK为我做了。我知道请求中的重复键:

REQUEST:

PATCH https://graph.microsoft.com/v1.0/users/jane.doe@contoso.onmicrosoft.com HTTP/1.1
SdkVersion: graph-dotnet-1.0.1
Authorization: Bearer <token>
Cache-Control: no-store, no-cache
Content-Type: application/json
Host: graph.microsoft.com
Content-Length: 478
Expect: 100-continue

{"accountEnabled":true,"businessPhones":[],"department":"department","displayName":"Jane Doe (department)","givenName":"Jane","surname":"Doe","userPrincipalName":"jane.doe@contoso.onmicrosoft.com","id":"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa","@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users/$entity","givenName":null,"jobTitle":null,"mail":null,"mobilePhone":null,"officeLocation":null,"preferredLanguage":null,"surname":null}

响应:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.5
request-id: 2c0437b3-2438-4a34-bf70-937bec2143d1
client-request-id: 2c0437b3-2438-4a34-bf70-937bec2143d1
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"SouthEast Asia","Slice":"SliceB","ScaleUnit":"001","Host":"AGSFE_IN_0","ADSiteName":"SIN"}}
Duration: 30.6384
X-Powered-By: ASP.NET
Date: Wed, 13 Jul 2016 03:08:14 GMT

142
{
  "error": {
    "code": "InternalServerError",
    "message": "Can not add property givenName to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.",
    "innerError": {
      "request-id": "2c0437b3-2438-4a34-bf70-937bec2143d1",
      "date": "2016-07-13T03:08:14"
    }
  }
}
0

2 个答案:

答案 0 :(得分:3)

我已将此跟踪到我们将JSON数据反序列化为各自模型的方式中的错误。模型属性归因于标准.NET数据协定。但是,我们使用NewtonSoft来完成实际的JSON工作。两者的组合导致属性的空值被错误地放入AdditionalData字典属性(对于未知值的“catch-all”存储桶)。

此问题的修复程序将在下一次SDK更新时发布。您可以向前追踪here

要解决短期问题,您可以遍历AdditionalData字典并删除密钥与模型上的已知属性匹配的任何条目。如果您在发送更新之前执行此操作,它应该可以正常工作。

更多详情

可以在我们的SDK之外一般地重现此错误。例如:

<!-- language: c# -->

public class User
{
    [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "name")]
    public string Name { get; set; }

    [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "department")]
    public string Department { get; set; }

    [JsonExtensionData(ReadData = true, WriteData = true)]
    public IDictionary<string, object> AdditionalData { get; set; }
}

void SomeFunction()
{
    string json = @"{ 'name': 'Bob Smith', 'department': null }";
    var user = JsonConvert.DeserializeObject<User>(json);

    // Inspecting user here will show the Name property with the correct
    // value, the Department property with a null value, but will also
    // have a "department = null" key / value pair incorrectly in the
    // AdditionalData property.
}

答案 1 :(得分:0)

您请求中的json数据无效,它添加了重复属性, givenName 姓氏,如下图所示:

enter image description here 请删除重复的一个并确保json数据已验证,您可以从here进行检查。

要更新用户,我们只需要提供我们想要的更改字段。例如,以下是为用户更新部门的示例:

 var user = graphserviceClient.Me.Request();
 var newUser = new User();
 newUser.Department = "dep1";
 var updateUser=await user.UpdateAsync(newUser);