我有一个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
Contacts
,GetExistingContacts()
存储为 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;
如果有人能帮我解释一下,那就太好了!
提前致谢
答案 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