十多年来,我们一直使用 C# 代码通过 EWS 与 Exchange 进行通信。事实上,我们所有的客户都已迁移到 Office 365,并且直到最近,我们的代码都通过 EWS 在 O365 上运行得非常好。
我们的软件处理 Exchange 邮箱中收到的电子邮件。该邮箱供人类和我们的软件使用,因此我们一直在使用 ExtendedProperty 来跟踪我们已处理的电子邮件。代码如下:
// Build our extended property definition
Guid readByEmailComponentGUID = new Guid("{FCF74ABF-684E-4cc7-8A83-B36D3A209219}"); //GUID for our property
ExtendedPropertyDefinition X_READBYCOMPONENT = new ExtendedPropertyDefinition(readByEmailComponentGUID, "X_READBYCOMPONENT", MapiPropertyType.Boolean); //Settings and name for our property
// Create a search filter for querying EWS
SearchFilter.SearchFilterCollection srchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.Or);
srchFilter.Add(new SearchFilter.Not(new SearchFilter.Exists(X_READBYCOMPONENT))); //Show messages that do not have our new property (thus have never been received)
srchFilter.Add(new SearchFilter.IsEqualTo(X_READBYCOMPONENT, false)); //Show messages that have our new property, but it's set to false (to re-receive)
ItemView view = new ItemView(250, 0, OffsetBasePoint.Beginning);
// Query EWS with our search filter and our view
FindItemsResults<Item> findResults = EWSService.FindItems("Inbox", srchFilter, view);
// Process the results of our search
foreach (Item item in findResults){
// Check to see if this email has our internal read flag on it, and if it does, do not process it again.
ExtendedProperty ReadByComponentFlag = item.ExtendedProperties.FirstOrDefault(itm => itm.PropertyDefinition == X_READBYCOMPONENT);
if (!(ReadByComponentFlag is null) && (bool)ReadByComponentFlag.Value == true)
{
continue;
}
if (item is EmailMessage){
EmailMessage em = item as EmailMessage; //Load the email message
// process the mail message and when that's done mark it as read
em.SetExtendedProperty(X_READBYCOMPONENT, true); //Sets our new property to TRUE to exclude this email from future receive actions
em.Update(ConflictResolutionMode.NeverOverwrite);
}
}
自 2011 年以来,该代码一直运行良好,但从大约一个月前开始,我们的 Office 365 客户的搜索过滤器出现故障,EWS 一直在返回每封电子邮件。检查电子邮件消息并手动查看其扩展属性,我可以看到我们的自定义属性存在,并且它仍然设置为 true。
O365 上的 EWS 处理这些过滤器的方式有什么变化吗?还有其他人遇到类似问题吗?
现在我们添加了一个解决方法(您可以在上面的代码中看到)来手动检查扩展属性并跳过电子邮件,但这不是一个可行的长期解决方案,因为其中一些邮箱中有 14,000 封电子邮件,我们每次运行都会提取和接收这些电子邮件。
我试图用相同的属性和逻辑重现该问题,但不能例如
var InboxFolder = Folder.Bind(exchangeService, WellKnownFolderName.Inbox);
// Create a search filter for querying EWS
// Build our extended property definition
Guid readByEmailComponentGUID = new Guid("{FCF74ABF-684E-4cc7-8A83-B36D3A209219}"); //GUID for our property
ExtendedPropertyDefinition X_READBYCOMPONENT = new ExtendedPropertyDefinition(readByEmailComponentGUID, "X_READBYCOMPONENT", MapiPropertyType.Boolean); //Settings and name for our property
Item it = InboxFolder.FindItems(new ItemView(1)).Items[0];
it.SetExtendedProperty(X_READBYCOMPONENT, true);
it.Update(ConflictResolutionMode.AutoResolve);
SearchFilter.SearchFilterCollection srchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.Or);
srchFilter.Add(new SearchFilter.Not(new SearchFilter.Exists(X_READBYCOMPONENT))); //Show messages that do not have our new property (thus have never been received)
srchFilter.Add(new SearchFilter.IsEqualTo(X_READBYCOMPONENT, false));
FindItemsResults<Item> findResults = InboxFolder.FindItems(srchFilter, new ItemView(100));
if(findResults.Items.Any(x => x.Id.UniqueId == it.Id.UniqueId))
{
Console.WriteLine("Item Found");
}
else
{
Console.WriteLine("Item not found");
}
Console.WriteLine("Done");
如果它发生在多个环境中的多个邮箱上,并且您可以构建一个测试装置并重现该问题,那么您应该将其记录为 Microsoft 的错误,因为这是您获得某种类型的牵引/修复的唯一方法。搜索过滤器不应打开失败,您可能还想在图表上尝试一下,看看是否存在相同的问题,例如在图表上查询会类似于
https://graph.microsoft.com/v1.0/me/mailFolders('Inbox')/messages? $filter=singleValueExtendedProperties/any(ep: ep/id eq 'Boolean {FCF74ABF-684E-4cc7-8A83-B36D3A209219} Name X_READBYCOMPONENT' and cast(ep/value, Edm.Boolean) eq null) OR singleValueExtendedProperties/any(ep: ep/id eq 'Boolean {FCF74ABF-684E-4cc7-8A83-B36D3A209219} Name X_READBYCOMPONENT' and cast(ep/value, Edm.Boolean) eq false)
您应该能够使用图形浏览器对其进行测试,如果您在图形中发现相同的问题,那么您也可以针对该问题创建一个错误。