【问题标题】:ASP.NET LDAP SearchResults Properties returning Byte ArrayASP.NET LDAP SearchResults 属性返回字节数组
【发布时间】:2017-03-07 23:13:40
【问题描述】:

我正在使用 DirectorySearcher 尝试获取 AD 中的用户列表,以将它们与我的应用程序同步,并从各种 SO 源复制代码,但是我没有获得任何属性值。我正在使用以下代码:

        DirectorySearcher search = new DirectorySearcher();
        SearchResultCollection results = null;
        string sDefaultOU = "LDAP://...";
        DirectoryEntry de = new DirectoryEntry(sDefaultOU);
        string userName = "DonaldDuck";
        search = new DirectorySearcher
        {
            SearchRoot = de,
            PropertiesToLoad = { "displayname", "sAMAccountName"}, 
            Filter = "(sAMAccountName=" + userName + ")"    
        };
        results = search.FindAll();

        foreach (SearchResult result in results)
        {
            String name; 
            if (result.Properties["sAMAccountName"].Count > 0)
            {
                name = result.Properties["sAMAccountName"][0].ToString();
            }    
        }

但是,名称不是等于“DonaldDuck”,而是“Byte[10]”或 Byte[x],其中 x 是长度。

谁能看到我做错了什么。

如果我添加一个过滤器,它会返回一个用户,所以我很确定代码在搜索方面是有效的

【问题讨论】:

    标签: c# asp.net active-directory ldap


    【解决方案1】:

    显然其他人也遇到过这个问题:LDAP DirectoryEntry SearchResult returns data differently in Windows 8 than Win7

    AD 使用 LDAPv3 对使用 UTF8 的值进行编码,上面链接中提到的解决方案可能适合您:

    if (result.Properties["sAMAccountName"][0].GetType().IsArray)
    {
        name = System.Text.Encoding.UTF8.GetString((byte[])result.Properties["sAMAccountName"][0]);
    }
    else
    {
        name = result.Properties["sAMAccountName"][0].ToString();
    }
    

    【讨论】:

    • 非常棒。我没有在任何地方发现这个,谢谢你
    【解决方案2】:

    而不是

    foreach (SearchResult result in results)
        {
            String name; 
            if (result.Properties["sAMAccountName"].Count > 0)
            {
                name = result.Properties["sAMAccountName"][0].ToString();
            }    
        }
    

    试试

    foreach (SearchResult result in results)
        {
            String name; 
            if (result.Properties["sAMAccountName"].Count > 0)
            {
                var thisDE=result.GetDirectoryEntry();
                name = thisDE.Properties["sAMAccountName"].Value.ToString();
            }    
        }
    

    编辑:示例 我使用这个辅助方法来搜索我的域(当 userDomainAndName="DOMAIN\UserName" 时),但您应该能够根据需要调整它。

     public static DirectoryEntry GetUserDirectoryEntryFromCurrentDomain(string userDomainAndName)
        {
            var Split = userDomainAndName.Split(@"\\".ToCharArray());
    
            var DomainNetBiosNAme = Split[0];
            var UserName = Split[1];
    
            var QueryString = $"(&(objectCategory=person)(objectClass=user)(sAMAccountName={UserName}))";
    
            DirectoryEntry rootDSE = GetDirectoryObject(
                "LDAP://" + DomainNetBiosNAme + "/rootDSE");
    
            string domain = "LDAP://" + (string)rootDSE.Properties[
                "defaultNamingContext"][0];
    
            var Searcher = new DirectorySearcher(new DirectoryEntry(domain), QueryString);
            var Result = Searcher.FindOne();
    
            var tReturn = Result.GetDirectoryEntry();
            return tReturn; 
    
        }
    

    然后获取我的用户 PrimarySMTP 地址(例如)..

    var TheUsersDirectoryEntry=GetUserDirectoryEntryFromCurrentDomain(userDomainAndName);
    var TheUsersPrimarySMTP=TheUsersDirectoryEntry.Properties["mail"].Value.ToString();
    

    【讨论】:

    • 谢谢。我之前尝试过,但在尝试获取名称时出现“异常详细信息:System.Runtime.InteropServices.COMException:未知错误(0x8000500c)”。
    • 8000500c 通常是权限被拒绝和/或不正确的 LDAP 路径错误。stackoverflow.com/questions/1722398/… 只是一个简单的问题,如果您已经知道 sAMAccountName,为什么还要尝试找回它?请查看我的编辑 - 我将添加我的工作帮助方法和使用示例..
    • 感谢您的所有帮助。在实践中,我会使用更具体的 OU 而不是添加过滤器。这只是为了限制响应,所以我有“好的”数据来调试
    • 当我在工作中训练新秀时,我最喜欢的口头禅之一是“测试你的测试”,我的意思是永远不要假设你的快速测试方法是正确的。这就是为什么我喜欢使用“工具箱方法”来创建经过测试和“已知良好”的代码库。我想你现在已经工作了,很高兴能提供帮助。 (哦,我刚刚在我的示例方法中发现了一个错字,我现在就去修复它)
    猜你喜欢
    • 2022-08-23
    • 2015-05-22
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    相关资源
    最近更新 更多