EWS + Exchange 2007:检索内嵌图像

时间:2011-07-11 13:30:24

标签: c# image inline exchangewebservices exchange-server-2007

使用EWS托管API在C#中工作,我们无法有效地检索存储为内联附件的图像。

端点是显示带有内嵌图像的电子邮件,作为面板中完全形成的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

..虽然效率不高,但正在降低我们网络应用的响应速度。有没有人有更好的解决方案来解决这个问题?我们使用的是Exchange 2007 SP1,因此IsInline属性不能仅用作Exchange 2010。

1 个答案:

答案 0 :(得分:8)

我建立了你的&#34; cid:&#34; s的索引:

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

中的小错误