通过System查询自定义LDAP属性.c#中的DirectoryServices
本文关键字:中的 DirectoryServices 属性 LDAP System 查询 自定义 通过 | 更新日期: 2023-09-27 18:18:05
我在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属性(并且确认picturePath存在于键列表中):
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属性。
更重要的是,只有当我读取值时,它才会失败;我可以看到属性在键列表中,我只是不能访问它。
不幸的是,未知的错误并没有告诉我很多关于什么是错的,但我找到了。net实现的系统。DirectoryServices非常不稳定(如果您使用小写的'DC='连接到LDAP服务器,您会得到相同的未知错误)。
以前有人遇到过这个问题吗?如果有,是如何解决的?
你应该检查两件事:
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
中的类实际上主要是针对活动目录的——当用于其他LDAP服务器(如OpenLDAP)时,可能会有"意外"或微妙的不兼容性。
看来。net LDAP客户端需要属性类型和对象类的正确形成的OID。
您将注意到我使用的是形式为999.X的oid。YY,虽然它们可能在语法上是正确的,但在现实世界中并不常见。我的猜测是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客户端现在正确地读取了自定义属性。