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