Ошибка сериализации Json при обновлении пользователя в Azure AD через GRAPH

c# json.net microsoft-graph azure-ad-graph-api

918 просмотра

2 ответа

98 Репутация автора

Я использую библиотеку Microsoft.Graph здесь, чтобы обновить пользователя в 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 с сообщением «Исключение типа« Microsoft.Graph.ServiceException »было сгенерировано».

При запуске 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 делает это для меня. Мне известно о дубликате ключа в запросе:

ЗАПРОС:

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
Автор: Stuart Meeks Источник Размещён: 12.07.2016 06:01

Ответы (2)


0 плюса

12029 Репутация автора

Данные json в вашем запросе недействительны, они добавили дублирующееся свойство, имя и фамилию, как показано ниже:

введите описание изображения здесь Удалите дубликат и убедитесь, что данные JSON проверены, вы можете проверить их здесь .

И чтобы обновить пользователя, нам нужно только предоставить измененное поле, которое мы хотели. Например, вот пример, который обновляет отдел для пользователя для вашей справки:

 var user = graphserviceClient.Me.Request();
 var newUser = new User();
 newUser.Department = "dep1";
 var updateUser=await user.UpdateAsync(newUser);
Автор: Fei Xue - MSFT Размещён: 14.07.2016 08:34

3 плюса

294 Репутация автора

Решение

Я отследил это до ошибки в том, как мы десериализовали данные JSON в их соответствующие модели. Свойства модели связаны со стандартными контрактами данных .NET. Тем не менее, мы используем NewtonSoft для выполнения реальной работы JSON. Сочетание этих двух значений приводит к тому, что нулевые значения свойств неправильно помещаются в свойство словаря AdditionalData («универсальная корзина» для неизвестных значений).

Исправление для этой проблемы будет выпущено со следующим обновлением SDK. Вы можете отслеживать это здесь, двигаясь вперед.

Чтобы обойти проблему в краткосрочной перспективе, вы можете перебрать словарь 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.
}
Автор: Robert Anderson - Microsoft Размещён: 28.07.2016 08:32
Вопросы из категории :
32x32