2011-07-11 4 views
2

En travaillant en C# avec l'API EWS Managed, nous avons de la difficulté à récupérer efficacement les images stockées en tant que pièces jointes en ligne.EWS + Exchange 2007: Récupérer des images en ligne

Le point de terminaison est d'afficher un e-mail avec des images en ligne en tant que page html entièrement formée dans un panneau. Le code que nous nous actuellement:

 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); 
      } 
     } 
     } 

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

.. ce n'est pas très efficace si et ralentit la réactivité de notre application web. Est-ce que quelqu'un a une meilleure solution pour ce problème? Nous utilisons Exchange 2007 SP1, donc la propriété IsInline ne fonctionnera pas comme Exchange 2010 uniquement.

Répondre

7

Je construis un index de votre "cid:" s première:

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; 
}  

Ensuite, vous besoin d'une fonction de remplacement qui remplace les CIDs en fonction de votre index

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; 
} 

maintenant, vous pouvez vérifiez vos pièces jointes

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; 
     } 
    } 
} 

supplémentaires que: au lieu d'appeler attachment.Load tout de suite, et passez le chemin à l'image directement, vous pouvez lier à un autre script, où vous passez le cid en tant que paramètre, puis revenez avec l'échange pour cette image; alors le processus de chargement de l'image depuis l'échange ne bloque pas le remplacement du cid html et pourrait conduire au chargement plus rapide de la page, puisque le html peut envoyer au navigateur plus tôt. PS: Le code n'est pas testé, juste pour avoir l'idée!

EDIT

Ajout de la fonction AdjustIndex manquante.

EDIT 2

petit Correction d'un bug dans AdjustIndex

Questions connexes