我几年前为Outlook编写了一个加载项,它根据Item的ConversationIndex
/ ConversationId
属性向数据库添加条目。这很好,并且在与消息交互的所有客户端之间保持一致(例如,“Bob”可以看到“Mary”已经处理了此消息,因为已经存在ConversationIndex
的条目。)
我现在正在尝试将此部分移动到服务(并通过EWS API连接),但我没有好运将这些属性与来自Outlook的值进行匹配。例如:
Outlook加载项会为我定位的特定电子邮件提供以下值:
ConversationID: 6B6369F5023EA646AA7BC161274BDAE8
ConversationIndex: 0101CF3C7EEC6B6369F5023EA646AA7BC161274BDAE8
但是,从EWS API我得到以下内容:
ConversationID: AAQkADFhZThkNmJmLTlkODItNDQyZS1hM2YxLTQ2NWNkMTllYjhjOQAQAGtjafUCPqZGqnvBYSdL2ug=
ConversationIndex: new byte[]{1,1,207,60,126,236,107,99,105,245,2,62,166,70,170,123,193,97,39,75,218,232}
我认为第一个是Base64编码的字符串,然而我解码的东西看起来并不像我认识的那样(或者可以解密)。有没有人熟悉这个,或谁可以帮助让这两个值对齐?我只能想象来自交换服务器的这些属性是某种方式,但客户端可能会执行一些清理,而EWS API只是给我原始值(减去Base64,因为我认为在给定XML介质的情况下运输目的)。
如果有人熟悉这个或已经做过,我会非常感谢任何指导。
旁注:
可能有更好的方法来识别电子邮件,但现在我仍然坚持尝试保持这两个同义词。修改outlook加载项实际上不是一个选项,一旦我将1:1的转换迁移到服务器(并删除加载项),我将灵活地改变它的工作方式。但是现在我需要它们并排运行。我需要能够从Web服务器中查看Outlook中的进程,反之亦然。
答案 0 :(得分:3)
刚刚发现(我认为)。
随着更多谷歌搜索和更多的努力,我相信我能够使用以下内容使它们以1:1对齐:
这显然是由几个属性组成的组合值。幸运的是,我能够找到一种方法,Woodman发布了重新实现Outlook original algorithm使用的here的方法。通过一些小的修改(与EWS而不是Outlook一起使用),我能够让它发挥作用。
结果只是使用BitConverter
(并删除连字符)。容易腻。
public static class EwsEmailMessageExtensions
{
private const int c_ulConvIndexIDOffset = 6;
private const int c_ulConvIndexIDLength = 16;
private static ExtendedPropertyDefinition PidTagConversationIndexTracking = new ExtendedPropertyDefinition(0x3016, MapiPropertyType.Boolean);
// HUGE props to Woodman
// https://stackoverflow.com/a/21625224/298053
public static string GetOutlookConversationId(this EmailMessage emailMessage)
{
Boolean convTracking;
if (!emailMessage.TryGetProperty(PidTagConversationIndexTracking, out convTracking))
{
convTracking = true;
}
var convIndex = emailMessage.ConversationIndex;
byte[] idBytes;
if (convTracking && convIndex != null && convIndex.Length > 0)
{
// get Id from Conversation index
idBytes = new byte[c_ulConvIndexIDLength];
Array.Copy(convIndex, c_ulConvIndexIDOffset, idBytes, 0, c_ulConvIndexIDLength);
}
else
{
// get Id from Conversation topic
var topic = emailMessage.ConversationTopic;
if (string.IsNullOrEmpty(topic))
{
return string.Empty;
}
if (topic.Length >= 265)
{
topic = topic.Substring(0, 256);
}
topic = topic.ToUpper();
using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider())
{
idBytes = md5.ComputeHash(Encoding.Unicode.GetBytes(topic));
}
}
return BitConverter.ToString(idBytes).Replace("-", string.Empty);
}
public static String GetOutlookConversationIndex(this EmailMessage emailMessage)
{
var convIndex = emailMessage.ConversationIndex;
return BitConverter.ToString(convIndex).Replace("-", String.Empty);
}
}
// Prep
ExchangeService service = new ExchangeService(...);
Folder inbox = Folder.bind(service, WellKnownFolderName.Inbox);
Item item = /* inbox.FindItems(...).First() */
// Implmentation
EmailMessage emailMessage = item as EmailMessage;
if (emailMessage != null)
{
String conversationId = emailMessage.GetOutlookConversationId();
String conversationIndex = emailMessage.GetOutlookConversationIndex();
/* ... */
}