EWS创建联系人将电子邮件转换为Exchange专有名称而不是SMTP

时间:2017-09-08 13:05:59

标签: exchangewebservices

我有一个C#控制台应用程序,它使用EWS (Exchange Web Services)来模拟用户,并创建或更新他当前的Contacts列表。

为了确定我是否必须创建或更新他的列表,我首先需要在现有的Contacts中搜索特定的域名,如下所示:

private static IEnumerable<Contact> GetExistingContacts(ExchangeService service)
{
    var domainToFilterOn = "@contoso.com";
    SearchFilter sfSearch = new SearchFilter.ContainsSubstring(ContactSchema.EmailAddress1, domainToFilterOn);
    FindItemsResults<Item> contacts = service.FindItems(WellKnownFolderName.Contacts, sfSearch, new ItemView(int.MaxValue));
    var results = contacts.Cast<Contact>().ToList();
    return results;
}

我遇到的问题是方法GetExistingContacts()为给定的域名产生了0结果,这是错误的,因为我知道我有一堆Contacts持有@contoso.com域名EmailAddre1字段中的名称。

经过一些挖掘和测试后,我终于弄明白为什么该方法没有返回任何结果,原因是因为电子邮件地址存储在 Exchange专有名称而不是 SMTP 格式。

为了进一步调查,我创建了一些新的Contacts,其中包含假冒/不存在的@contoso.com域名,如:test@contoso.com, gazou@contoso.com, etc.

令我惊讶的是,GetExistingContacts()方法开始返回这些假的Contacts

结论是,每当我创建具有Contacts的新resolvable email addresses时,这些Contacts都会使用 Exchange专有名称进行存储,但是当我创建新的时候Contacts non-resolvable email addresses ContactsGetExistingContacts()存储为 SMTP (由我的EmailAddress1方法返回)。

如何开始修复此问题?

我的搜索方法有误吗?是否有其他方法可以在.Load()字段内搜索?

与此同时,我设法使用Contact对象的private static IEnumerable<Contact> GetCurrentContacts(ExchangeService service) { var contacts = new List<Contact>(); var data = service.FindItems(WellKnownFolderName.Contacts, new ItemView(int.MaxValue)); foreach (var item in data.Items) { if (item is Contact) { item.Load(); contacts.Add(item as Contact); } } var result = contacts.Where(x => x.EmailAddresses[EmailAddressKey.EmailAddress1].Address.Contains("@contoso.com")).ToList(); return result; } 方法找到了解决方法,但这种解决方法在执行时间方面看起来很丑陋且代价高昂。

我基本上获取所有Contacts,循环并调用Load()方法,然后将它们添加到List()并生成Linq查询以过滤结果。如果我的用户有800个联系人,则需要很长时间才能加载()所有人。 这是一个例子:

RoutingType

毋庸置疑,我认为这不是正确的方法,尽管它有效。

我尝试过的另一个替代方法是强制RoutingType认为SMTP会以SMTP格式创建新的联系人而不是 Exchange专有名称但不幸的是,电子邮件地址仍然存储在 Exchange专有名称中,而不管我强制var email = new EmailAddress(); email.Address = "goodemail@contoso.com"; email.RoutingType = "SMTP"; Contact contact = new Contact(service); contact.EmailAddresses[EmailAddressKey.EmailAddress1] = email; ... contact.Save(); 如此:

set spark.executor.extraJavaOptions=-Xss16m;
set hive.execution.engine=spark;

如果有人能帮我解释一下,那就太好了!

提前致谢

2 个答案:

答案 0 :(得分:0)

如果您尝试用于联系人的SMTP地址在全局地址列表中可见(或可解析),则目录条目的X500地址将用于跟踪目录条目的联系人(这是设计使然)。如果要在检索联系人时返回SMTP地址而不是X500地址,您需要做的就是使用您在联系人或联系人的托管API中执行GetItem或加载,如果您有多个联系人使用LoadPropertiesFromItems https://blogs.msdn.microsoft.com/exchangedev/2010/03/16/loading-properties-for-multiple-items-with-one-call-to-exchange-web-services/

您可以通过直接在联系人上设置扩展属性来覆盖此行为,请参阅https://social.technet.microsoft.com/Forums/exchange/en-US/2b375c56-bee1-4d88-b638-f95649ef964a/use-ews-create-a-contact-which-has-a-same-email-address-in-gal-it-will-show-up-with-x500-formatting?forum=exchangesvrdevelopment,但我建议您继续使用默认行为,使用批量加载可以提高代码效率。

答案 1 :(得分:0)

感谢@Glen Scales,LoadPropertiesForItems()帮助。

如果有人关心,这是最终结果:

private static IEnumerable<Contact> GetExistingContacts(ExchangeService service)
{
    var contacts = new List<Contact>();
    var filterContactsOnDomain = "@contoso.com";
    var data = service.FindItems(WellKnownFolderName.Contacts, new ItemView(int.MaxValue));
    if (data.TotalCount > 0)
    {
        service.LoadPropertiesForItems(data, new PropertySet(ContactSchema.EmailAddress1));
        foreach (var item in data.Items)
        {
            if (item is Contact)
            {
                contacts.Add(item as Contact);
            }
        }
    }

    var result = contacts.Where(x => x.EmailAddresses[EmailAddressKey.EmailAddress1].Address.ToLower().Contains(filterContactsOnDomain.ToLower())).ToList();
    return result;
}

我唯一不喜欢的是必须获取所有联系人(其中800个),为所有800个加载EmailAddress1字段,循环并将这800个联系人添加到列表中,然后过滤该列表... < / p>

我想能够直接在X500电子邮件地址格式上搜索(或过滤),因此无需获取所有800个联系人。

哦,好吧......

再次感谢@Glen Scales