2
votes

Can someone give me a hint how to set the User.Manager field using the Microsoft Graph .NET Client Library? I know how to do this via a direct REST call but want to avoid those calls (bypassing the wrapper) as much as possible. With the code below I was able to clear the manager property.

client = new GraphClient(...);
var builder = new DirectoryObjectWithReferenceRequestBuilder(
    client.Users["<userid>"].Manager.Request().RequestUrl,client
);
builder.Request().DeleteAsync().Wait()

However, I still can't figure out which class allows me to build a PUT request for the member reference (as described here). I tried to the following code:

var mgr = new DirectoryObject();
mgr.Id = "<Id of the user that should be set as manager>";

var usrPatch = new User();
usrPatch.Manager = mgr;

client.Users["<Id of the user to be updated>"].Request().UpdateAsync(usrPatch).Wait();

This code doesn't throw an exception but it also doesn't update the manager. The request is wrong. The above code sends a PATCH instead of a PUT to the "base" object.

Request generated by the code above:

PATCH https://graph.microsoft.com/v1.0/users/[Id of the user to be updated] HTTP/1.1
SdkVersion: graph-dotnet-1.0.1 
Content-Type: application/json 
Host: graph.microsoft.com 
Content-Length: 45 Expect: 100-continue

{"id":"[Id of the user that should be set as manager]"}

The response is a 204.

4
It looks like this might be a gap in the library. Thanks for pointing this out. Let me check and get back to you.Dan Kershaw - MSFT

4 Answers

2
votes

I see the following to remove a manager:

graphClient.Users[newUser.Id].Manager.Reference.Request().DeleteAsync();

But we should have something like the following to assign a manager:

graphClient.Users[newUser.Id].Manager.Reference.Request().AddAsync(manager);

I'll file a bug for this and update when fixed.

0
votes

Workaround till updating the "manager" is fully supported:

var authToken = "<get your token here>";
var client = new GraphClient(...);

var usrId = "<id of the user to update>"
var mgrId = "<id of the manager>"

var url = client.Users[usrId].Manager.Reference.Request().RequestUrl;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", authToken);

var content = new StringContent(
    client.HttpProvider.Serializer.SerializeObject(
        new ReferenceRequestBody
        {
            ODataId =
                $"{client.BaseUrl}/directoryObjects/{mgrId}"
        }),
    Encoding.Default,
    "application/json");

var resp = httpClient.PutAsync(url, content).Result;
if (!resp.IsSuccessStatusCode)
{
    // throw exception/log etc
}
0
votes

Two years later and this is still not working.

I'm getting the following exception when using await graphClient.Users[user.Id].Manager.Request().UpdateAsync(usrPatch);

Microsoft.Graph.ServiceException: 'Code: BadRequest
Message: Write requests are only supported on contained entities

I had to use stefboe's workaround logic to update the manager.

Microsoft.Graph DLL Version is 1.12.

0
votes

Use PutAsync() to set the manager using the Graph Library: graphClient.Users[user.Id].Manager.Reference.Request().PutAsync(manager.Id);