See this example, UserService.CreateUserWithCustomAttribute()
: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C
public static async Task CreateUserWithCustomAttribute(GraphServiceClient graphClient, string b2cExtensionAppClientId, string tenantId)
{
if (string.IsNullOrWhiteSpace(b2cExtensionAppClientId))
{
throw new ArgumentException("B2C Extension App ClientId (ApplicationId) is missing in the appsettings.json. Get it from the App Registrations blade in the Azure portal. The app registration has the name 'b2c-extensions-app. Do not modify. Used by AADB2C for storing user data.'.", nameof(b2cExtensionAppClientId));
}
// Declare the names of the custom attributes
const string customAttributeName1 = "FavouriteSeason";
const string customAttributeName2 = "LovesPets";
// Get the complete name of the custom attribute (Azure AD extension)
Helpers.B2cCustomAttributeHelper helper = new Helpers.B2cCustomAttributeHelper(b2cExtensionAppClientId);
string favouriteSeasonAttributeName = helper.GetCompleteAttributeName(customAttributeName1);
string lovesPetsAttributeName = helper.GetCompleteAttributeName(customAttributeName2);
Console.WriteLine($"Create a user with the custom attributes '{customAttributeName1}' (string) and '{customAttributeName2}' (boolean)");
// Fill custom attributes
IDictionary<string, object> extensionInstance = new Dictionary<string, object>();
extensionInstance.Add(favouriteSeasonAttributeName, "summer");
extensionInstance.Add(lovesPetsAttributeName, true);
try
{
// Create user
var result = await graphClient.Users
.Request()
.AddAsync(new User
{
GivenName = "Casey",
Surname = "Jensen",
DisplayName = "Casey Jensen",
Identities = new List<ObjectIdentity>
{
new ObjectIdentity()
{
SignInType = "emailAddress",
Issuer = tenantId,
IssuerAssignedId = "casey.jensen@example.com"
}
},
PasswordProfile = new PasswordProfile()
{
Password = Helpers.PasswordHelper.GenerateNewPassword(4, 8, 4)
},
PasswordPolicies = "DisablePasswordExpiration",
AdditionalData = extensionInstance
});
string userId = result.Id;
Console.WriteLine($"Created the new user. Now get the created user with object ID '{userId}'...");
// Get created user by object ID
result = await graphClient.Users[userId]
.Request()
.Select($"id,givenName,surName,displayName,identities,{favouriteSeasonAttributeName},{lovesPetsAttributeName}")
.GetAsync();
if (result != null)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine($"DisplayName: {result.DisplayName}");
Console.WriteLine($"{customAttributeName1}: {result.AdditionalData[favouriteSeasonAttributeName].ToString()}");
Console.WriteLine($"{customAttributeName2}: {result.AdditionalData[lovesPetsAttributeName].ToString()}");
Console.WriteLine();
Console.ResetColor();
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
}
}
catch (ServiceException ex)
{
if (ex.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Have you created the custom attributes '{customAttributeName1}' (string) and '{customAttributeName2}' (boolean) in your tenant?");
Console.WriteLine();
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
If you want you can avoid using the helpers at the top. The string key in the extensionInstance
dictionary will be "extension_{app id}_{property name}" where the {app id} is the id of the default app created for you with the name b2c-extensions-app. Do not modify. Used by AADB2C for storing user data.