c# - EWS + 交换 2007 : Retrieve inline images

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

在 C# 中使用 EWS Managed API,我们在有效检索存储为内联附件的图像时遇到了问题。

端点是在面板中将带有内联图像的电子邮件显示为完全形成的 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 使用。

最佳答案

我首先为您的“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;
}       

然后你需要一个替换函数,根据你的索引替换 cids

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 中的小错误

关于c# - EWS + 交换 2007 : Retrieve inline images,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6650842/

相关文章:

javascript - RequireJS - 在需求流和内联中加载 AMD 模块

c# - 在 C# 中双击时如何让窗体永远不会进入全屏

c# - 配置 Unity 以解析构造函数参数和接口(interface)

javascript - 根据js中的颜色的数字/百分比填充图像

image - 使用 png 或 svg 图像作为 graphviz 节点

javascript - module.exports 内联函数变量未定义

c# - 我如何解析这个 XML(没有得到 "Root element is missing"或 "Sequence contains no elements")?

c# - 为什么在 System.IO 的 Directory 类中有 Move 方法,但没有 Copy 方法?

iPhone/iPad 背景图片

c - 强制静态函数内联有什么缺点吗?