Tuesday 24 April 2007

Active directory service interface reference

I needed to retrive some values from Ldap and for some properties I was not able to retrieve its value. I used standard classes from namespace System.DirectoryServices and always got System.Runtime.InteropServices.COMException(0x8000500c). After some investigation I found that for access to Ldap I can use ADSI interface. I found that the property I wanted to get was of octet string datatype. Unfortunatelly I did not managed to find how to retrieve valuo of the property though PropertyCollection. I was able to find that the collection contains the property, but I could not read its value.

At first I used something like that:

// works almost for everything, but not for octet strings (array of bytes)
// properties is of type PropertyCollection from System.DirectoryServices
string value = string.Empty;

if (properties.Contains(key))
{
value = properties[key].Value.ToString();
}


Solution of the problem:

string value = string.Empty;

try
{
// if the item do not exists exception is thrown
ActiveDs.IADsPropertyEntry entry = ActiveDs.IADsPropertyEntry)propertyList.Item(key);

// get types
int propertyType = entry.ADsType;
int valueType = (ActiveDs.IADsPropertyValue)((object[])((ActiveDs.IADsPropertyEntry)propertyList.GetPropertyItem(key, propertyType)).Values)[0]).ADsType;

switch (valueType)
{
// for octet string (array of bytes) we have to create string
case (int)ActiveDs.ADSTYPEENUM.ADSTYPE_OCTET_STRING:
value = Sstem.Text.Encoding.ASCII.GetString((byte[])((ActiveDs.IADsPropertyValue)((object[])((ActiveDs.IADsPropertyEntry)propertyList.GetPropertyItem(key, propertyType)).Values)[0]).OctetString);
break;

// for all others - all current properties are of this type
case (int)ActiveDs.ADSTYPEENUM.ADSTYPE_CASE_IGNORE_STRING:
value = ((ActiveDs.IADsPropertyValue)((object[])((ActiveDs.IADsPropertyEntry)propertyList.GetPropertyItem(key, propertyType)).Values)[0]).CaseIgnoreString;
break;
// in other cases you can add new section
}
catch (System.Runtime.InteropServices.COMException cex)
{
if (cex.ErrorCode == -2147463155)
Trace.Write(cex);
else throw;
}


In this case you have to add to your references Activeds.dll.

No comments: