leo*_*ora 16 c# outlook vsto exchange-server exchangewebservices
我有以下代码通过某个字符串搜索全局通讯簿:
"CONF"
var esb = new ExchangeServiceBinding();
esb.Url = @"https://myurl.com/EWS/Exchange.asmx";
esb.Credentials = new NetworkCredential(_user,_pwd, _domain);
var rnType = new ResolveNamesType {ReturnFullContactData = true, UnresolvedEntry = "CONF"};
ResolveNamesResponseType response = esb.ResolveNames(rnType);
ArrayOfResponseMessagesType responses = resolveNamesResponse.ResponseMessages;
var responseMessage = responses.Items[0] as ResolveNamesResponseMessageType;
ResolutionType[] resolutions = responseMessage.ResolutionSet.Resolution;
Run Code Online (Sandbox Code Playgroud)
问题是它似乎正在进行"开始"搜索,所以我有一个名字叫:
它将显示"CONF-123",但如果我有一个名字"JOE-CONF",那么它就不会出现.
如何在此行上进行部分字符串搜索
var rnType = new ResolveNamesType {ReturnFullContactData = true, UnresolvedEntry = "CONF-"};
Run Code Online (Sandbox Code Playgroud)
我希望有类似的东西:
var rnType = new ResolveNamesType {ReturnFullContactData = true, UnresolvedEntry = "%CONF-%"};
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用.
编辑: 2016年1月4日 - 添加了搜索AD的示例代码.
什么是行不通的
通过ResolveNames搜索GAL始终使用前缀字符串匹配来进行模糊名称解析(ARN).虽然EWS文档没有明确说明,但Exchange ActiveSync文档可以.EWS和Exchange ActiveSync只是协议; 它们都依赖于ARN,因此无论您使用的是ActiveSync协议还是EWS,都会遇到前缀匹配问题.
以下是Exchange ActiveSync文档的相关引用(https://msdn.microsoft.com/en-us/library/ee159743%28v=exchg.80%29.aspx)
提供给Search命令的文本查询字符串用于前缀字符串匹配
.
什么会奏效
最好的办法取决于你的用例,但这里有一些想法:
在您的客户端程序中搜索Active Directory(包含您在问题中显示的代码的程序)
设置您自己的服务以搜索GAL.您的客户端程序将连接到Exchange和您的服务.或者您的服务可以代理EWS,因此客户端程序只需要连接到您的服务.
您将如何获得GAL数据?一种方法是重复使用EWS ResolveNames,一次获取GAL数据,100个条目,并在服务中缓存这些数据.首先,检索所有"a",然后检索所有"b"等.当然,GAL中可以有超过100个"a",所以只需获取所有"a"就可以进行多次搜索 - 您将根据每次搜索返回的最后一个条目构建下一个搜索字符串.这可能是缓慢而痛苦的.您可能希望将此数据缓存在数据库中并定期刷新.
您也可以通过MAPI访问GAL.您可以直接使用MAPI(https://msdn.microsoft.com/en-us/library/cc765775%28v=office.12%29.aspx)或通过帮助库(如Redemption)(http://www.dimastr. com/redemption/home.htm).无论是直接使用MAPI还是通过Redemption,都需要在运行代码的计算机上安装Outlook(或Exchange).由于此限制,最好不要在客户端程序中使用MAPI,而是将其粘贴在某个服务器上运行的服务中,并让客户端程序连接到该服务.
AD代码示例
另一个答案提供了搜索Active Directory的示例代码.我正在添加一个代码示例,可能更适合通过搜索找到此问题的人员的通用用法.与其他示例相比,下面的代码具有以下改进:
如果搜索字符串包含任何特殊字符(如括号),则对它们进行转义,以使构造的过滤字符串有效.
通过samaccountname搜索许多是不够的.如果"David Smith"的帐户名为"dsmith",则通过samaccountname搜索"David"将找不到他.我的示例演示了如何通过更多字段进行搜索,并提供了一些可能要搜索的字段.
从像"GC:"这样的根开始比尝试从Domain.GetComputerDomain()构建LDAP条目更强大.
IDisposable必须处理所有s(通常在using构造中使用它们).
// Search Active Directory users.
public static IEnumerable<DirectoryEntry> SearchADUsers(string search) {
// Escape special characters in the search string.
string escapedSearch = search.Replace("*", "\\2a").Replace("(", "\\28")
.Replace(")", "\\29").Replace("/", "\\2f").Replace("\\", "\\5c");
// Find entries where search string appears in ANY of the following fields
// (you can add or remove fields to suit your needs).
// The '|' characters near the start of the expression means "any".
string searchPropertiesExpression = string.Format(
"(|(sn=*{0}*)(givenName=*{0}*)(cn=*{0}*)(dn=*{0}*)(samaccountname=*{0}*))",
escapedSearch);
// Only want users
string filter = "(&(objectCategory=Person)(" + searchPropertiesExpression + "))";
using (DirectoryEntry gc = new DirectoryEntry("GC:")) {
foreach (DirectoryEntry root in gc.Children) {
try {
using (DirectorySearcher s = new DirectorySearcher(root, filter)) {
s.ReferralChasing = ReferralChasingOption.All;
SearchResultCollection results = s.FindAll();
foreach (SearchResult result in results) {
using (DirectoryEntry de = result.GetDirectoryEntry()) {
yield return de;
}
}
}
} finally {
root.Dispose();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)小智 0
对索引文本字段的模糊搜索只能使用前缀(或后缀...)来完成。这就是为什么 Exchange 可能将查询实现为 LIKE 'CONF%'。
我查看了文档,没有任何方法可以绕过它 - 全表扫描(%CONF% 必须如此)似乎没有意义。
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |