搜索全局地址列表时,有没有办法进行部分搜索而不仅仅是"startsWith"

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)

但这似乎不起作用.

Geo*_*rge 5

编辑: 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% 必须如此)似乎没有意义。