Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clarification on how to update (patch) objects using the Microsoft.Graph Client

The following code is the only way I found so far to update an object using the Microsoft Graph Client Library

Scenario:

  1. Load an exisiting object (an organization)
  2. Modify a value (add entry in securityComplianceNotificationPhones)
  3. Send the update

Code

var client = new GraphServiceClient(...);

var org = client.Organization["orgid"].Request().GetAsync().Result;
var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");

var patchOrg = new Organization();
patchOrg.SecurityComplianceNotificationPhones = secPhones;

var orgReq = new OrganizationRequest(
     client.Organization[org.Id].Request().RequestUrl,
     client, new Option[] {});
orgReq.UpdateAsync(patchOrg).Wait();

I needed to use the patchOrg instance because of two things:

  1. The Graph API documentation states

    "In the request body, supply the values for relevant fields that should be updated. Existing properties that are not included in the request body will maintain their previous values or be recalculated based on changes to other property values. For best performance you shouldn't include existing values that haven't changed."

  2. If you actually do include existing values that haven't changed (i.e. assginedLicenses) the request fails, if those existing values are readonly.

My question is: Is/will there be a more straightforward way of updating existing objects like for example in the Azure ActiveDirectory GraphClient? Just for comparison, the same scenario in Azure Active Directory Graph

var client = new ActiveDirectoryClient(...);
var org = client.TenantDetails.GetByObjectId("orgid").ExecuteAsync().Result;
org.SecurityComplianceNotificationPhones.Add("12345");
org.UpdateAsync().Wait();
like image 254
stefboe Avatar asked Apr 21 '16 13:04

stefboe


1 Answers

The Graph client library model is slightly different from the older SDK model the AAD client library you linked. The older model passed around objects that tried to be a bit smarter and reason about which properties were changed, only sending those. One of the main drawbacks of this model was that the library made many more service calls in the background and had a much heavier payload in each call since ExecuteAsync() would often need to retrieve every object in the request builder chain. The newer library does require the developer to do more explicit reasoning about what data is being passed but also gives greater control over network calls and payload. Each model has its tradeoffs.

To accomplish what you want, here's the approach I would recommend instead of creating a second org object altogether:

var client = new GraphServiceClient(...);

var orgRequest = client.Organization["orgid"].Request();
var org = orgRequest.Select("securityComplianceNotificationPhones").GetAsync().Result;

var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");

org.SecurityComplianceNotificationPhones = secPhones;

orgRequest.UpdateAsync(org).Wait();
like image 134
ginach Avatar answered Nov 13 '22 05:11

ginach