2011-07-11 56 views
2

使用EWS Managed API在C#中工作时,我们无法高效地检索以内联附件存储的图像。EWS + Exchange 2007:检索内嵌图像

端点将在面板中显示带有内嵌图像的电子邮件作为完整形成的html页面。代码我们目前我们:

 string sHTMLCOntent = item.Body; 

     FileAttachment[] attachments = null; 

     if (item.Attachments.Count != 0) 
     { 
     attachments = new FileAttachment[item.Attachments.Count]; 
     for (int i = 0; i < item.Attachments.Count; i++) 
     { 
      string sType = item.Attachments[i].ContentType.ToLower(); 
      if (sType.Contains("image")) 
      { 
      attachments[i] = (FileAttachment)item.Attachments[i]; 
      string sID = attachments[i].ContentId; 
      sType = sType.Replace("image/", ""); 
      string sFilename = sID + "." + sType; 
      string sPathPlusFilename = Directory.GetCurrentDirectory() + "\\" + sFilename; 
      attachments[i].Load(sFilename); 
      string oldString = "cid:" + sID; 
      sHTMLCOntent = sHTMLCOntent.Replace(oldString, sPathPlusFilename); 
      } 
     } 
     } 

(来源:http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/ad10283a-ea04-4b15-b20a-40cbd9c95b57

..这是不是很有效,但并放慢我们的web应用程序的响应能力。有没有人有这个问题的更好的解决方案?我们使用的是Exchange 2007 SP1,因此IsInline属性只能用作其Exchange 2010。

回答

7

我建立自己的指数“CID:”第一个:

private const string CidPattern = "cid:"; 

private static HashSet<int> BuildCidIndex(string html) 
{ 
    var index = new HashSet<int>(); 
    var pos = html.IndexOf(CidPattern, 0); 
    while (pos > 0) 
    { 
     var start = pos + CidPattern.Length; 
     index.Add(start); 
     pos = html.IndexOf(CidPattern, start); 
    } 
    return index; 
}  

然后,你需要一个替换功能,取代了CID的基于索引

private static void AdjustIndex(HashSet<int> index, int oldPos, int byHowMuch) 
{ 
    var oldIndex = new List<int>(index); 
    index.Clear(); 
    foreach (var pos in oldIndex) 
    { 
     if (pos < oldPos) 
      index.Add(pos); 
     else 
      index.Add(pos + byHowMuch); 
    }   
} 

private static bool ReplaceCid(HashSet<int> index, ref string html, string cid, string path) 
{ 
    var posToRemove = -1; 
    foreach (var pos in index) 
    { 
     if (pos + cid.Length < html.Length && html.Substring(pos, cid.Length) == cid) 
     { 
      var sb = new StringBuilder(); 
      sb.Append(html.Substring(0, pos-CidPattern.Length)); 
      sb.Append(path); 
      sb.Append(html.Substring(pos + cid.Length)); 
      html = sb.ToString(); 

      posToRemove = pos; 
      break; 
     } 
    } 

    if (posToRemove < 0) 
     return false; 

    index.Remove(posToRemove); 
    AdjustIndex(index, posToRemove, path.Length - (CidPattern.Length + cid.Length)); 

    return true; 
} 

所以现在,你可以检查您的附件

FileAttachment[] attachments = null; 
var index = BuildCidIndex(sHTMLCOntent); 
if (index.Count > 0 && item.Attachments.Count > 0) 
{ 
    var basePath = Directory.GetCurrentDirectory(); 

    attachments = new FileAttachment[item.Attachments.Count]; 
    for (var i = 0; i < item.Attachments.Count; ++i) 
    { 
     var type = item.Attachments[i].ContentType.ToLower(); 
     if (!type.StartsWith("image/")) continue;      
     type = type.Replace("image/", ""); 

     var attachment = (FileAttachment)item.Attachments[i]; 
     var cid = attachment.ContentId; 
     var filename = cid + "." + type; 
     var path = Path.Combine(basePath, filename); 
     if(ReplaceCid(index, ref sHTMLCOntent, cid, path)) 
     { 
     // only load images when they have been found   
     attachment.Load(path); 
     attachments[i] = attachment; 
     } 
    } 
} 

此外:不要致电attachment.Load,并将路径直接传递到图像,您可以链接到另一个脚本,在那里您传递cid作为参数,然后检查该图像的交换;那么从交换机加载图像的过程不会阻止html cid替换,并且可能导致加载页面的速度更快,因为html可以更快地发送到浏览器。 PS:代码没有经过测试,只是让你明白!

编辑

添加缺少的AdjustIndex功能。

编辑2

固定的小缺陷在AdjustIndex

相关问题