c# - C# Exchange Web 服务 - 发送并立即检索已发送的消息
问题描述
我正在使用的系统要求将MimeContent
刚刚发送的电子邮件存储在本地数据库中。我对 Exchange 工作原理的理解是,它将MimeContent
在服务器上创建,除非我查询服务以获取刚刚发送的消息,否则我无法访问它。
所以,我采取的步骤是:
-- 发送电子邮件并得到它Id
message.SendAndSaveCopy();
return message.Id.UniqueId;
-- 使用新的id获取刚刚发送的EmailMessage
ExchangeService exchangeService = ExchangeService;
var properties = new List<PropertyDefinitionBase>
{
ItemSchema.MimeContent
};
EmailMessage message = EmailMessage.Bind(exchangeService, new ItemId(messageId), new PropertySet(BasePropertySet.IdOnly, properties));
当这段代码不间断地运行时,它就可以工作。返回的Id
仍然有效(消息可能在发件箱文件夹中),我得到了结果。但是,如果我将其放慢一秒钟,则 Id 将不再有效(我猜它现在已移至已发送的文件夹中)。
我不能这样离开它,因为不能保证我会及时回到服务器以检索带有它的消息Id
。
如果有一个解决方案让我不必再次查询服务以获取消息,那就太好了。但是,如果没有,有没有办法可以使用Id
andChangeKey
来获取刚刚发送的电子邮件?
解决方案
最终回答了我自己的问题。我通过在我控制的每封电子邮件上添加一个自定义属性来做到这一点。然后我使用相同的值来搜索电子邮件。我在查询之间的文件夹之间移动电子邮件时遇到了一些问题,但它现在已排序。
在某处定义它,我在我的 EmailProvider 类中有它:
private readonly PropertyDefinitionBase _TempEmailId = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "TempEmailId", MapiPropertyType.String);
然后在发送电子邮件之前添加它:
string messageId = null; if (getTempId) { messageId = Guid.NewGuid().ToString(); message.SetExtendedProperty((ExtendedPropertyDefinition) _TempEmailId, messageId); } message.SendAndSaveCopy(); return messageId;
最后,使用
messageId
获取MimeContent
(或您想要的任何其他属性):/// <summary> /// Get the mime content for an email just sent /// </summary> /// <param name="messageId"></param> /// <returns></returns> public byte[] GetJustSentMimeContent(string messageId) { ExchangeService exchangeService = ExchangeService; // Use the following search filter to get mail with TempEmailId set to what we just got var searchCriteria = new SearchFilter.IsEqualTo(_TempEmailId, messageId); var itemView = new ItemView(1) {PropertySet = new PropertySet(BasePropertySet.IdOnly)}; byte[] GetMimeContent(WellKnownFolderName folder) { var items = exchangeService.FindItems(folder, searchCriteria, itemView); if (items.TotalCount > 0) { // if it's still in there, try and load the properties for it exchangeService.LoadPropertiesForItems(items, new PropertySet(BasePropertySet.IdOnly, ItemSchema.MimeContent)); var emailMessage = (EmailMessage) items.First(); // if the content has been loaded, return it if (emailMessage.MimeContent != null) return emailMessage.MimeContent.Content; } return null; } // check the drafts folder to see if it's still in there var mimeContent = GetMimeContent(WellKnownFolderName.Drafts); if (mimeContent != null) return mimeContent; // if at this point, either: // - email was moved to SentItems before the first search was done // - or email was found in Drafts but then moved to SentItems but before the MimeContent could be loaded. Need to restart the process and find the email in SentItems instead // should be in here (sentItems) now, try and load the properties for it return GetMimeContent(WellKnownFolderName.SentItems); }
推荐阅读
- parsing - 为上下文敏感的标记语言编写词法分析器,具有递归结构,例如嵌套列表
- xamarin - Xamarin.Forms 检测自定义 ContentView 单击外部事件
- c# - 如何在 ASP.NET Core MVC 中使用数据库中的数据制作下拉列表
- delphi - 将 EPSG:2180 中的 X、Y 转换为
- sql - 禁用触发器语法 (Oracle)
- linq - LinqToSql 表不返回任何对象
- neo4j - Neo4j 和 Electron 的结合
- r - 哪些 R 包适合绘制随时间推移的疾病传播?
- javascript - ng2charts 使用带有数组值的borderColor
- pagination - 如何在不使用库文件的情况下在 Codeigniter 中设置分页