Reputation: 932
I am currently trying to use Graph Client Library Version 2.0 to interact with my Azure Active Directory. I want to add a new attribute to the users so I need to use Schema Extensions. I followed the tutorial here: http://justazure.com/azure-active-directory-part-6-schema-extensions, and example code here: https://github.com/AzureADSamples/ConsoleApp-GraphAPI-DotNet.
My code:
public async Task setAccountNumber(string UserName, String AccountNumber)
{
////Register an Extension Property in Azure AD which is the account number
////Define the account number property
//ExtensionProperty accountNumber = new ExtensionProperty()
//{
// Name = "AccountNumber",
// DataType = "String",
// TargetObjects = { "User" }
//};
//// Get a reference to our application
//Microsoft.Azure.ActiveDirectory.GraphClient.Application app =
// (Microsoft.Azure.ActiveDirectory.GraphClient.Application)activeDirectoryClient.Applications.Where(
// a => a.AppId == Constants.ClientId).ExecuteSingleAsync().Result;
//// Register the extension property
//app.ExtensionProperties.Add(accountNumber);
//await app.UpdateAsync();
ExtensionProperty accountNumber = new ExtensionProperty()
{
Name = "AccountNumber",
DataType = "String",
TargetObjects = { "User" }
};
//Get the user
User user = (User)activeDirectoryClient.Users.Where(u => u.UserPrincipalName.Equals(
UserName, StringComparison.CurrentCultureIgnoreCase)).ExecuteSingleAsync().Result;
//Set the Account Number property
if (user != null)
{
user.SetExtendedProperty(accountNumber.Name, AccountNumber);
await user.UpdateAsync();
// Save the extended property value to Azure AD.
//user.GetContext().SaveChanges();
}
// Retrieve the extension property value for a user for test use only!
IReadOnlyDictionary<string, object> extendedProperties = user.GetExtendedProperties();
object extendedProperty = extendedProperties["AccountNumber"];
}
I used commented lines to create a new extension property which is user's account number. And I use the following code to find a new user and set the account number of this user.
However, I got this error:
{"odata.error": {
"code":"Request_BadRequest",
"message": {
"lang":"en",
"value":"One or more extension property values specified are invalid."
},
"values":null}}
At line: await user.UpdateAsync();
The Stack Trace:
[DataServiceClientException: {"odata.error":{"code":"Request_BadRequest","message":{"lang":"en","value":"One or more extension property values specified are invalid."},"values":null}}]
[DataServiceRequestException: An error occurred while processing this request.]
System.Data.Services.Client.SaveResult.HandleResponse() +1038
System.Data.Services.Client.BaseSaveResult.EndRequest() +262
System.Data.Services.Client.DataServiceContext.EndSaveChanges(IAsyncResult asyncResult) +121
System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) +99
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +49
Microsoft.Azure.ActiveDirectory.GraphClient.Extensions.<SaveChangesAsync>d__74.MoveNext() +1694
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
DataIngestionAPI.Managers.<setAccountNumber>d__c.MoveNext() in c:\Users\Jason\Source\Repos\UCDavis Water\UCDavisResearchPlatform\DataIngestionAPI\Managers\AzureADManager.cs:107
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
DataIngestionAPI.Controllers.<Registration>d__6.MoveNext() in c:\Users\Jason\Source\Repos\UCDavis Water\UCDavisResearchPlatform\DataIngestionAPI\Controllers\HomeController.cs:123
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
System.Threading.Tasks.TaskHelpersExtensions.ThrowIfFaulted(Task task) +89
System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +110
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +92
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +71
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +141
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +65
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +189
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +717
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +66
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +71
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +141
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +65
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +103
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +330
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +71
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +73
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +58
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +90
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +188
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +73
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +50
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +68
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +60
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +85
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +73
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +50
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +58
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +93
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +188
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +196
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +73
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +50
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +58
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +59
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +282
Any help is appreciated.
Upvotes: 1
Views: 1802
Reputation: 5828
So I managed to reproduce the issue. Basically the error message means that the service cannot find the extension property that you are looking for. The issue with your code is that you are specifying "AccountNumber" as the extension name. However extensions have the format "extension_appId_extensionName" to ensure extension name uniqueness. NOTE: appId here is the appId (aka clientId) GUID of your app, but without the dashes - i.e. xxxx-xxx-xxx becomes xxxxxxxxxx.
So the simplest thing to do is to construct the extension property name using the syntax above - in your case it would be "extension_appId_AccountName", substituting your application's appId/clientId here.
I think this might have happened because you copied our sample, where then full extension name is in memory, since in the sample we just created the extension, so we just use it from there. I might change the sample to "construct" the full extension name (as per the syntax above).
Also for more information on directory schema extensions, please see https://msdn.microsoft.com/en-us/library/azure/dn720459.aspx
Hope this helps,
Upvotes: 4