在 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);
}
}
}
.. 这不是很有效,并且正在减慢我们网络应用程序的响应速度。有人对此问题有更好的解决方案吗?我们使用的是 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/