How to avoid “The directory data type cannot be converted to/from a native DS data type” (0x8000500C) in managed code
Hello everyone,
We may find ourselves in the situation where we need to access custom properties that have been defined for objects in our Active Directory. However, using the managed class DirectoryEntry
we may receive an exception with the error code 0x8000500CL when accessing the custom property the following way:
myDirectoryEntry.Properties["myProperty"]
As the error text indicates, the cause for this issue is the lack of information about how to convert the value of our custom property into a managed object. DirectoryEntry
does not offer the possibility to specify this meta information, so how can we access our custom properties?
Luckily there is COM library, ActiveDS, which exposes (amongst others) the following two functions:
IADsPropertyList::GetPropertyItem
IADsPropertyList::PutPropertyItem
Once we add a reference to the library to our Visual Studio project, selecting it from the COM tab (it appears as "Active DS Type Library"), we can implement a wrapper like the following:
class PropertyHelper { public static List GetProperty(DirectoryEntry entry, String propertyName, ADSTYPEENUM adsType) { // make sure to get the properties from the DC entry.RefreshCache(new String[] { propertyName }); // get the property list from the underlying native object IADsPropertyList propList = (IADsPropertyList)entry.NativeObject; // return values List values = new List(); // get the native property object IADsPropertyEntry propEntry = (IADsPropertyEntry)propList.GetPropertyItem(propertyName, (int)adsType); // iterate over the values set for the property foreach (IADsPropertyValue propValue in propEntry.Values) { switch (adsType) { case ADSTYPEENUM.ADSTYPE_CASE_IGNORE_STRING: values.Add(propValue.CaseIgnoreString); break; case ADSTYPEENUM.ADSTYPE_CASE_EXACT_STRING: values.Add(propValue.CaseExactString); break; case ADSTYPEENUM.ADSTYPE_DN_STRING: values.Add(propValue.DNString); break; case ADSTYPEENUM.ADSTYPE_INTEGER: values.Add(propValue.Integer); break; case ADSTYPEENUM.ADSTYPE_BOOLEAN: values.Add(propValue.Boolean); break; case ADSTYPEENUM.ADSTYPE_LARGE_INTEGER: values.Add(propValue.LargeInteger); break; case ADSTYPEENUM.ADSTYPE_OCTET_STRING: values.Add(propValue.OctetString); break; default: throw new System.NotImplementedException("Handling of this ADSTYPE is not implemented"); } } return values; } }
We can then access our custom property using the following call:
var sReturnValues = PropertyHelper.GetProperty(entry, "sAttribute", ADSTYPEENUM.ADSTYPE_CASE_IGNORE_STRING);
Implementing a similar wrapper for setting the values of our custom property should be straightforward from here. I hope this helps.
Cheers,
Helge Mahrt
Comments
Anonymous
February 05, 2015
but ,how to update customer property ? Error again when update one entry customer property ....Anonymous
February 05, 2015
Now,I do another way! Delete Entry ,then ,add new entry (new propertys).....but ,not the best way