Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set extension (extended) property #28

Open
aloneguid opened this issue Jan 20, 2016 · 11 comments
Open

Cannot set extension (extended) property #28

aloneguid opened this issue Jan 20, 2016 · 11 comments

Comments

@aloneguid
Copy link

I have no success in setting extended property whatever I do. I have isolated the reproducible piece of code:

      public async Task CleanTest(string extName)
      {
         ExtensionProperty ep = new ExtensionProperty
         {
            Name = extName,
            DataType = "String",
            TargetObjects = { "User" }
         };

         App app = (App)(await _client.Applications.Where(a => a.AppId == _managementAppClientId).ExecuteSingleAsync());
         app.ExtensionProperties.Add(ep);
         await app.UpdateAsync();

         GraphUser user = (GraphUser)(await _client.Users.Where(u => u.UserPrincipalName.Equals("email")).ExecuteSingleAsync());
         string propName = FormatExtensionPropertyName(extName); //formats properly as extesion_xxx_name
         user.SetExtendedProperty(propName, "testvalue");
         //user.SetExtendedProperty(extName, "testvalue");
         await user.UpdateAsync(); // fails here
      }

user.UpdateAsync() according to Fiddler doesn't even go out and application fails with an exception:

"The property 'extension_e206e28ff36244b19bc56c01160b9cf0_UserEEEqdbtgd3ixx2' does not exist on type 'Microsoft.Azure.ActiveDirectory.GraphClient.Internal.User'. Make sure to only use property names that are defined by the type."

@ronanscally
Copy link

I am also having this issue - has there been an Active Directory update?

@aloneguid
Copy link
Author

@ronanscally hey, i still wasn't able to solve this. I think there was an update, I also tried to keep downgrading Client Library version by version and can reproduce the issue straight away, therefore not a Client Library issue.

@aloneguid
Copy link
Author

Does anyone have any update on this?

@tonipohl
Copy link

tonipohl commented Mar 4, 2016

no, unfortunately still having the same issues.... :(
I will ask in the Azure Advisors Yammer Network with your post.

@aloneguid
Copy link
Author

Thanks. Please keep us posted, this bug is eating me alive.

@ecosgrave
Copy link

This bug seems to have been introduced between Graph API library that depends on Microsoft.Data.Services.Client v5.7, compared to v5.6.4. I was able to workaround the problem either use assembly redirects in my App.config, or reverting back to the v5.6.4 package.

@DaCheeseMan
Copy link

I'm still struggling. I have this method that should create an extended property, but when it hits the await application.UpdateAsync() line, my simple console project exits. Any ideas?
`private static async Task Run()
{
Uri serviceRoot = new Uri(serviceRootURL);
ActiveDirectoryClient _adClient = new ActiveDirectoryClient(serviceRoot, async () => await GetAppTokenAsync());

var application = (Application)_adClient.Applications.Where(app => app.AppId.Equals(clientID, StringComparison.InvariantCultureIgnoreCase)).ExecuteSingleAsync().Result;
bool isExtended = false;
foreach (var item in application.ExtensionProperties)
{
    if (item.Name.Equals("reachOutClientInstallKey", StringComparison.CurrentCultureIgnoreCase))
    {
        isExtended = true;
        break;
    }
}

if (!isExtended)
{
    ExtensionProperty reachOutClientInstallKey = new ExtensionProperty
    {
        Name = "reachOutClientInstallKey",
        DataType = "String",
        TargetObjects = { "User" }
    };
    ExtensionProperty reachOutClientInstallSecret = new ExtensionProperty
    {
        Name = "reachOutClientInstallSecret",
        DataType = "String",
        TargetObjects = { "User" }                    
    };
    application.ExtensionProperties.Add(reachOutClientInstallKey);
    application.ExtensionProperties.Add(reachOutClientInstallSecret);                
    await application.UpdateAsync();
    Console.WriteLine("Done!");
    Console.ReadLine();
}

}
`

This is my packages.config
`

`

@normanhh3
Copy link

normanhh3 commented Jul 19, 2016

This is affecting me as well.

Oddly enough, I can test my exact same code out in LinqPAD and it works just fine. When I run it in my actual app is when it starts failing on me.

Folks over here on SO are wondering similar things.

Looks like this issue might be the one that resolves it.

Alas, I ended up actually just reverting to 5.6.4.0 like everyone else.

@ecosgrave
Copy link

Alternative Workaround (v5.7 compatible)

I've got an alternative workaround for this bug, for those that want to use the version 5.7 OData libraries rather than redirecting to the v5.6.4 versions.
Thanks to various contributors on this thread for hints that pointed me to this end.

Add a request pipeline configuration handler.

// initialize in the usual way
ActiveDirectoryClient activeDirectoryClient = 
  AuthenticationHelper.GetActiveDirectoryClientAsApplication();
// after initialization add a handler to the request pipline configuration.
activeDirectoryClient.Context
  .Configurations.RequestPipeline
  .OnMessageWriterSettingsCreated(UndeclaredPropertyHandler);

In the handler, change the ODataUndeclaredPropertyBehaviorKinds value on the writer settings to SupportUndeclaredValueProperty.

private static void UndeclaredPropertyHandler(MessageWriterSettingsArgs args)
{
  var field = args.Settings.GetType().GetField("settings", 
    BindingFlags.NonPublic | BindingFlags.Instance);
  var settingsObject = field?.GetValue(args.Settings);
  var settings = settingsObject as ODataMessageWriterSettings;
  if (settings != null)
  {
    settings.UndeclaredPropertyBehaviorKinds = 
       ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty;
  }
}

Some background for those that care.

Looking at the stack trace produced from the error: "The property 'extension_....' does not exist on type 'Microsoft.Azure.ActiveDirectory.GraphClient.Internal.User'. Make sure to only use property names that are defined by the type."

Error: System.Data.Services.Client.DataServiceRequestException An error occurred while processing this request.
   at System.Data.Services.Client.DataServiceContext.EndSaveChanges(IAsyncResult asyncResult)
-- snip --
Caused by: Microsoft.Data.OData.ODataException
   at Microsoft.Data.OData.WriterValidationUtils.ValidatePropertyDefined(String propertyName, IEdmStructuredType owningStructuredType, ODataUndeclaredPropertyBehaviorKinds undeclaredPropertyBehaviorKinds)
-- snip --
   at System.Data.Services.Client.Serializer.WriteEntry(EntityDescriptor entityDescriptor, IEnumerable`1 relatedLinks, ODataRequestMessageWrapper requestMessage)
-- snip --

The ValidatePropertyDefined() is passed a ODataUndeclaredPropertyBehaviorKinds value that is None by default, by changing that value to SupportUndeclaredValueProperty we can avoid the exception.

So look at the WriteEntry() method further up the stack, it creates a new ODataMessageWriter with ODataMessageWriterSettings. There is no way to customize these settings that I could find, they are created as a local instance and never exposed outside of WriteEntry().

However, we can plug into the writer pipeline through the Context.Configurations object. The handler passed to OnMessageWriterSettingsCreated is passed a MessageWriterSettingsArgs with that ODataMessageWriterSettings instance.

The MessageWriterSettingsArgs object contains a shim (of type DataServiceClientMessageWriterSettingsShim) for the settings but we need
to get to the underlying settings object (of type ODataMessageWriterSettings). Its a private field a little bit of reflection is required; naughty.
Once we get that, change the UndeclaredPropertyBehaviorKinds and we are done.

A more intelligent handler would only switch the value for the specific methods you need. No guarantees of what side-effects might be, but in my testing it works fine.

Tested and working with the latest packages (at time of writing):

Microsoft.Azure.ActiveDirectory.GraphClient version="2.1.0"
Microsoft.Data.Edm version="5.7.0"
Microsoft.Data.OData version="5.7.0"
Microsoft.Data.Services.Client version="5.7.0" 
Microsoft.IdentityModel.Clients.ActiveDirectory version="3.13.4" 
System.Spatial version="5.7.0"

Enjoy!

@normanhh3
Copy link

normanhh3 commented Mar 8, 2017

@ecosgrave your solution worked for me with the following versions.

<package id="Microsoft.Azure.ActiveDirectory.GraphClient" version="2.1.1" targetFramework="net452" /> <package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net452" /> <package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net452" /> <package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net452" /> <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.13.8" targetFramework="net452" /> <package id="System.Spatial" version="5.8.2" targetFramework="net452" />

@SlyW
Copy link

SlyW commented Apr 9, 2020

Sure would be nice to see this fixed - ended up having to use the workaround in version 5.8.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants