C#:如何将特殊字符写入 ADLDS?
C#: How to write special characters to ADLDS?
我正在尝试将联系人写入 ADLDS ldap,以便将它们用作 Yealink T48G 的 phone 电子书。有时联系人的姓名包含一些特殊字符,如“ö”、“ß”和“é”。如果这些字符包含在 "givenName" 或 "displayName" 字段中,phone 和 ldap 客户端都不能正确显示它们,而是显示一些其他字符(例如“ö” -> “à ¶"),但是 "name" 和 "dn" 字段正确显示这些字符。
如果我通过 ADSI-Edit 或任何其他工具插入联系人值,phone 会正确显示名称,但我的应用程序不再能够从 givenName 读取插入的特殊字符并显示一些问号-框,但是 dn 和名称字段读取正确。
我已经尝试使用 utf-8、utf-16、utf-32、iso-8859-1 和 windows-1252 作为我的应用程序的编码。
所以问题是如何使用 C# 在 ADLDS 实例中的 inetOrgPerson 的 givenName 属性 中存储这些特殊字符?
正确显示:
显示不正确:
我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.Protocols;
using System.Net;
namespace LdapContacts
{
public class LdapClient
{
private LdapConnection connection;
public LdapClient(string host, int port, string distinguishedUsername, string password)
{
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.AuthType = AuthType.Basic;
connection.Credential = new NetworkCredential(distinguishedUsername, password);
connection.Bind();
}
public AddResponse SendAddRequest(string distinguishedName, List<DirectoryAttribute> attributes)
{
AddRequest request = new AddRequest(distinguishedName, attributes.ToArray());
return connection.SendRequest(request) as AddResponse;
}
public SearchResponse SendSearchRequest(string distinguishedName, string filter)
{
SearchRequest request = new SearchRequest();
request.DistinguishedName = distinguishedName;
request.Filter = filter;
request.Scope = SearchScope.Subtree;
return connection.SendRequest(request) as SearchResponse;
}
}
public class ContactsToLdap
{
private static void Main(string[] args)
{
LdapClient client = new LdapClient(Settings.LdapHost, Settings.LdapPort, Settings.LdapUsername, Settings.LdapPassword);
client.SendAddRequest("CN=Testöäüß,CN=Users,CN=testpart,DC=csdomain,DC=local", new List<DirectoryAttribute>()
{
new DirectoryAttribute("telephoneNumber", "0123456"),
new DirectoryAttribute("objectClass", "inetOrgPerson"),
new DirectoryAttribute("uid", "io3e"),
new DirectoryAttribute("givenName", "â é testnameöüÄß")
});
//distinguished name of contactsfolder
SearchResponse result = client.SendSearchRequest(Settings.LdapContactsFolder, "(objectClass=inetOrgPerson)");
foreach (SearchResultEntry sResult in result.Entries)
{
//display the index of the current entry
Console.Write((result.Entries.IndexOf(sResult) + 1) + ":\n");
foreach (DirectoryAttribute attribute in sResult.Attributes.Values)
{
//output the name of the attribute
Console.Write("\t" + attribute.Name + " = ");
for (int i = 0; i < attribute.Count; i++)
{
// convert the attribute to a string if it is an byte[]
// output if inserted with ADSI-Edit: ? ? testname????
// output if inserted with this code: â é testnameöüÄß
if (attribute[i].GetType().Equals(typeof(byte[])))
{
Console.Write(Encoding.UTF8.GetString((byte[])attribute[i]) + "; ");
}
else
{
Console.Write(attribute[i] + "; ");
}
}
Console.WriteLine();
}
Console.WriteLine();
}
}
}
}
已通过将应使用的协议版本设置为版本 3 解决了该问题。
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.SessionOptions.ProtocolVersion = 3;
我正在尝试将联系人写入 ADLDS ldap,以便将它们用作 Yealink T48G 的 phone 电子书。有时联系人的姓名包含一些特殊字符,如“ö”、“ß”和“é”。如果这些字符包含在 "givenName" 或 "displayName" 字段中,phone 和 ldap 客户端都不能正确显示它们,而是显示一些其他字符(例如“ö” -> “à ¶"),但是 "name" 和 "dn" 字段正确显示这些字符。
如果我通过 ADSI-Edit 或任何其他工具插入联系人值,phone 会正确显示名称,但我的应用程序不再能够从 givenName 读取插入的特殊字符并显示一些问号-框,但是 dn 和名称字段读取正确。
我已经尝试使用 utf-8、utf-16、utf-32、iso-8859-1 和 windows-1252 作为我的应用程序的编码。
所以问题是如何使用 C# 在 ADLDS 实例中的 inetOrgPerson 的 givenName 属性 中存储这些特殊字符?
正确显示:
显示不正确:
我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.Protocols;
using System.Net;
namespace LdapContacts
{
public class LdapClient
{
private LdapConnection connection;
public LdapClient(string host, int port, string distinguishedUsername, string password)
{
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.AuthType = AuthType.Basic;
connection.Credential = new NetworkCredential(distinguishedUsername, password);
connection.Bind();
}
public AddResponse SendAddRequest(string distinguishedName, List<DirectoryAttribute> attributes)
{
AddRequest request = new AddRequest(distinguishedName, attributes.ToArray());
return connection.SendRequest(request) as AddResponse;
}
public SearchResponse SendSearchRequest(string distinguishedName, string filter)
{
SearchRequest request = new SearchRequest();
request.DistinguishedName = distinguishedName;
request.Filter = filter;
request.Scope = SearchScope.Subtree;
return connection.SendRequest(request) as SearchResponse;
}
}
public class ContactsToLdap
{
private static void Main(string[] args)
{
LdapClient client = new LdapClient(Settings.LdapHost, Settings.LdapPort, Settings.LdapUsername, Settings.LdapPassword);
client.SendAddRequest("CN=Testöäüß,CN=Users,CN=testpart,DC=csdomain,DC=local", new List<DirectoryAttribute>()
{
new DirectoryAttribute("telephoneNumber", "0123456"),
new DirectoryAttribute("objectClass", "inetOrgPerson"),
new DirectoryAttribute("uid", "io3e"),
new DirectoryAttribute("givenName", "â é testnameöüÄß")
});
//distinguished name of contactsfolder
SearchResponse result = client.SendSearchRequest(Settings.LdapContactsFolder, "(objectClass=inetOrgPerson)");
foreach (SearchResultEntry sResult in result.Entries)
{
//display the index of the current entry
Console.Write((result.Entries.IndexOf(sResult) + 1) + ":\n");
foreach (DirectoryAttribute attribute in sResult.Attributes.Values)
{
//output the name of the attribute
Console.Write("\t" + attribute.Name + " = ");
for (int i = 0; i < attribute.Count; i++)
{
// convert the attribute to a string if it is an byte[]
// output if inserted with ADSI-Edit: ? ? testname????
// output if inserted with this code: â é testnameöüÄß
if (attribute[i].GetType().Equals(typeof(byte[])))
{
Console.Write(Encoding.UTF8.GetString((byte[])attribute[i]) + "; ");
}
else
{
Console.Write(attribute[i] + "; ");
}
}
Console.WriteLine();
}
Console.WriteLine();
}
}
}
}
已通过将应使用的协议版本设置为版本 3 解决了该问题。
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.SessionOptions.ProtocolVersion = 3;