【问题标题】:C# and VB.NET LDAP Search Different?C# 和 VB.NET LDAP 搜索有何不同?
【发布时间】:2011-08-29 17:52:50
【问题描述】:

有谁知道 C# 和 VB.NET 中 DirectorySearcher 对象上 FindAll() 方法的实现是否有区别?据我了解,它们都被“编译”为 MSIL,并由 CLR 以相同的方式处理。针对我们的 ADAM/LDAP 系统,下面的 C# 代码会引发错误,而下面的 VB.NET 不会。

这是 C# 异常堆栈:

at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
  at System.DirectoryServices.DirectorySearcher.FindAll()

这是 C# 错误:

System.Runtime.InteropServices.COMException was unhandled
Message="The parameter is incorrect.\r\n"
Source="System.DirectoryServices"
ErrorCode=-2147024809

C#代码:

private void button1_Click(object sender, EventArgs e)
{
    DirectoryEntry root = new DirectoryEntry("LDAP://directory.corp.com/OU=Person,OU=Lookups,O=Corp,C=US", null, null, AuthenticationTypes.Anonymous);
    DirectorySearcher mySearcher = new DirectorySearcher(root);

    mySearcher.Filter = "(uid=ssnlxxx)";
    mySearcher.PropertiesToLoad.Add("cn");
    mySearcher.PropertiesToLoad.Add("mail");

    SearchResultCollection searchResultCollection = null;
    searchResultCollection = mySearcher.FindAll(); //this is where the error occurs

    try
    {
        foreach (SearchResult resEnt in searchResultCollection)
        {
            Console.Write(resEnt.Properties["cn"][0].ToString());
            Console.Write(resEnt.Properties["mail"][0].ToString());
        }
    }
    catch (DirectoryServicesCOMException ex)
    {
        MessageBox.Show("Failed to connect LDAP domain, Check username or password to get user details.");
    }
}

这是有效的 VB.NET 代码:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click

    Dim root As New     DirectoryEntry("LDAP://directory.corp.com/OU=People,OU=Lookups,O=corp,C=US", vbNull, vbNull, authenticationType:=DirectoryServices.AuthenticationTypes.Anonymous)
    Dim searcher As New DirectorySearcher(root)
    searcher.Filter = "(uid=ssnlxxx)"
    searcher.PropertiesToLoad.Add("cn")
    searcher.PropertiesToLoad.Add("mail")

    Dim results As SearchResultCollection

    Try
        results = searcher.FindAll()

        Dim result As SearchResult
        For Each result In results
            Console.WriteLine(result.Properties("cn")(0))
            Console.WriteLine(result.Properties("mail")(0))
        Next result
    Catch ex As Exception
        MessageBox.Show("There was an error")
    End Try
End Sub

【问题讨论】:

  • 异常信息是什么?
  • 我不确定这是否能解决您的问题(所以我在评论而不是“回答...”)但在您的 c# 代码中您可能会更改 @987654325 @到@"LDAP://directory.corp.com/OU=Person,OU=Lookups,O=Corp,C=US"。 @ 符号告诉 C# 编译器忽略转义字符,这是 C# 和 VB.NET 之间可能直接影响此问题的少数区别之一。
  • VB.NET 代码中的vbNull 是什么?这与Nothing 不同吗?
  • 我还注意到您在两种语言之间发现了不同的异常。尝试捕获相同的异常,看看是否得到相同的结果。
  • vbNull 是 VarType 返回的值,表示变体没有类型。它不等同于 c# NULL - 为此使用 vb 关键字 Nothing。

标签: c# .net vb.net exception-handling ldap


【解决方案1】:

我猜想在 VB.NET 代码中,您在 DirectoryEntry 构造函数和 C# 代码中为 DirectoryEntry 构造函数中的两个参数传入 vbNull(而不是 NothingnullvbNull 可能来自邪恶的 Microsoft.VisualBasic 程序集,不应使用。

DirectoryEntry 的构造函数检查用户名和密码参数以查看它们是否为空。如果vbNull != Nothing,构造函数不会将它们视为null,并且会表现不同。

如果您使用Nothing,请查看VB.NET 代码是否引发异常,或者使用String.Empty 而不是null 来查看C# 代码是否有效。

此外,在您的 C# 代码中,对 FindAll 的调用位于 try 块之外。

【讨论】:

  • 谢谢。那很有帮助。我会考虑你的建议。
  • 你解决了!将 DirectoryEntry 对象的构造函数中的空值更改为 String.Empty 解决了该问题。 COM 层不能喜欢空值。它必须需要一个空字符串。非常感谢!
  • @user477871 欢迎来到 Stack Overflow。很高兴您得到您的回答,请花点时间“接受”@Graham 的回答,以认可他对您的帮助。花点时间熟悉一下常见问题解答stackoverflow.com/faq
【解决方案2】:

C# 和 VB.NET 都没有实现 DirectorySearcher 或 .NET 的任何其他部分。它们都是 .NET Framework 的一部分。

【讨论】:

  • 谢谢。我意识到最终这个功能是在框架而不是语言中。类似于 java 和 JVM。这并不能真正回答我的问题。
  • 您询问是否存在“C# 和 VB.NET 中 DirectorySearcher 对象上 FindAll() 方法的实现之间的差异”。答案是“不,因为该对象在 .NET 中,而不是在 C# 或 VB.NET 中”。因此,如果您的两个代码示例之间存在差异,那就是另外一回事了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多