Search code examples
c#asp.net-coreazure-active-directorymicrosoft-graph-apimicrosoft-graph-sdks

Unable To Add User To AD Via C# Graph API -- Why Is This "OData Error" Occurring When Calling GraphServiceClient.Users.PostAsync()?


When attempting to Add/Invite a User to Azure AD Default Directory via Microsoft Graph in C#, as per MS Documentation:

var requestBody = new User
{
  AccountEnabled = true,
  DisplayName = "StackOverflow TestUser",
  MailNickname = "Stackie",
  Mail = "test@tempmailin.com",
  PasswordProfile = new PasswordProfile
  {
    ForceChangePasswordNextSignIn = false,
    Password = "testpwabcd",
  }
};
var result = await graphServiceClient.Users.PostAsync(requestBody);

The following Exception is caught upon attempting the Post:

Microsoft.Graph.Models.ODataErrors.ODataError: 'Exception of type 'Microsoft.Graph.Models.ODataErrors.ODataError' was thrown.'

This exception was originally thrown at this call stack:
    [External Code]

"[External Code]" is formatted just like that, and does not provide any further information (Probably referring to the C# Code calling the API.). I've been unable to find any way to pass in OData to Users.PostAsync(). The Graph Client is connected via a Client Secret:

var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential);

I've verifed that the Graph Client is properly connected, as it is able to properly Get a User:

User user1 = await graphServiceClient.Users["TestGUID-12345678910"].GetAsync();

And also able to successfully add an existing user in AD to a Group:

var requestBody2 = new Microsoft.Graph.Models.ReferenceCreate
{
  OdataId = "https://graph.microsoft.com/v1.0/directoryObjects/12345TestUserID",
};
await graphServiceClient.Groups["GroupID"].Members.Ref.PostAsync(requestBody2);

Trying var result = await graphServiceClient.Invitations.PostAsync(requestBody); fails with the same Error. Alternatively, var differentTry = graphServiceClient.Users.ToPostRequestInformation(requestBody); does pass through, with the following Object Parameters returned:Var Parameters For Users.ToPostRequest() Call However, the user is not added to AD.

I've tried the .Request.AddAsync(User) method (await _graphServiceClient.Users.Request().AddAsync(user);) in other helpful Articles, like this one by DamienBod, but I think that it is deprecated, as the Compiler throws Errors upon using it.

The API Permissions of the Tenant whose Settings are Configured for the Graph Client are as follows: API Permissions For Microsoft Graph Tenant &+ App.

Has anyone experienced this Error before and found a way around it, or alternatively does anyone know another way to add a User to Azure AD Default Directory via Microsoft Graph in C#? Thanks so much!

Edit: As per Tiny Wang's Answer Below, adding the "UserPrincipalName" to the requestBody with an E-Mail Address using the #EXT# + Domain Extension fixed the problem!


Solution

  • I reproduced your issue like below

    enter image description here

    and

    enter image description here

    and my code like this worked well,

    enter image description here

    I think the issue is related to userPrincipalName which had a description here

    this should map to the user's email name. The general format is alias@domain, where domain must be present in the tenant's collection of verified domains.

    Code I used:

    using Microsoft.Graph;
    using Azure.Identity;
    
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var tenantId = "tenant_name.onmicrosoft.com";
    var clientId = "aad_app_id";
    var clientSecret = "client_secret";
    var clientSecretCredential = new ClientSecretCredential(
                    tenantId, clientId, clientSecret);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
                
    var requestBody = new User
    {
        AccountEnabled = true,
        DisplayName = "StackOverflow TestUser",
        MailNickname = "Stackie",
        //UserPrincipalName = "test@tempmailin.com",
        UserPrincipalName = "test@tenantName.onmicrosoft.com",
        PasswordProfile = new PasswordProfile
        {
            ForceChangePasswordNextSignIn = false,
            Password = "8uhb*UHB",
        }
    };
    var result = await graphClient.Users.PostAsync(requestBody);