EWS + Exchange 2007: получение встроенных изображений

При работе на C# с управляемым API EWS возникают проблемы с эффективным получением изображений, хранящихся в виде встроенных вложений.

Конечной точкой является отображение электронного письма со встроенными изображениями в виде полностью сформированной 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.


person pierre    schedule 11.07.2011    source источник
comment
полный образец? что такое item.Body?   -  person PreguntonCojoneroCabrón    schedule 31.03.2018


Ответы (1)


Сначала я создаю индекс ваших "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 в качестве параметра, а затем проверяете обмен для этого изображения; то процесс загрузки изображения с биржи не блокирует замену cid html и может привести к более быстрой загрузке страницы, так как html может быстрее отправить в браузер. PS: Код не тестировался, просто чтобы вы поняли!

ИЗМЕНИТЬ

Добавлена ​​недостающая функция AdjustIndex.

ИЗМЕНИТЬ 2

Исправлена ​​небольшая ошибка в AdjustIndex.

person esskar    schedule 24.11.2011