通过C#中的System.DirectoryServices查询自定义LDAP属性?

时间:2011-12-18 00:47:41

标签: c# asp.net .net ldap openldap

我的OpenLDAP服务器上安装了自定义LDAP架构,如下所示:

attributeType ( 999.0.01
    NAME 'picturePath'
    EQUALITY caseIgnoreMatch
    SUBSTR caseIgnoreSubstringsMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
    )

objectClass ( 999.1.01
    NAME 'indieStackTeam'
            DESC 'Team definition for IndieStack'
    SUP groupOfUniqueNames
    STRUCTURAL
            MAY     ( picturePath )
    )

在我的ASP.NET MVC 2应用程序中,我正在查询picturePath属性(并且确认了keysPath存在于键列表中):

this.Picture = properties["picturePath"].Value as string;

当我尝试在.NET 3.5下执行此操作时,我得到以下异常:

[COMException (0x8000500c): Unknown error (0x8000500c)]   
    System.DirectoryServices.PropertyValueCollection.PopulateList() +347013
    System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) +49   
    System.DirectoryServices.PropertyCollection.get_Item(String propertyName) +150

但是,当相同的代码在Mono下运行时(在与OpenLDAP相同的服务器上),它可以正常工作。 LDAPAdmin等客户端也可以正确读取picturePath属性。

更重要的是,只有当我去读它失败的价值时才会这样;我可以在键列表中看到属性,我无法访问它。

不幸的是,未知错误并没有告诉我很多关于出了什么问题,但我发现System.DirectoryServices的.NET实现非常不稳定(如果使用小写连接到LDAP服务器,则会出现相同的未知错误在'DC =')。

之前有没有人遇到过这个问题,如果是的话,它是如何解决的?

2 个答案:

答案 0 :(得分:3)

你应该检查两件事:

1)该特定用户对象确实具有picturePath中的值吗?您可能希望在访问之前检查该属性是否存在:

if(properties.Contains("picturePath") && properties["picturePath"].Count > 0)
{
   ....
}

2)如果我没记错,要获得对自定义属性的访问权限,您应该在执行任何操作之前显式刷新用户对象的缓存:

DirectoryEntry de = ......;  // find / assign that DirectoryEntry somehow

de.RefreshCache();  // to load all properties from the directory

或:

de.RefreshCache(new string[] { "picturePath" });  // to just load the "picturePath" attribute

另外:System.DirectoryServices中的类实际上主要用于对抗Active Directory - 当用于某些其他LDAP服务器(如OpenLDAP)时,可能存在“意外”或微妙的不兼容性。

答案 1 :(得分:0)

似乎.NET LDAP客户端需要为属性类型和对象类正确形成OID。

你会注意到我正在使用999.X.YY形式的OID,虽然它们可能在语法上是正确的,但在现实世界中通常不会遇到。我的猜测是LDAP客户端解析OID,因为它们不符合预期,它会引发错误。

我分别将OID更改为1.3.6.1.4.1.40000.1.3.1和1.3.6.1.4.1.40000.1.4.1(我还申请了一个PEN,它会给我一个指定的数字而不是'40000' ),刷新服务器中的模式并重新创建条目,LDAP客户端现在可以正确读取自定义属性。