首页 > 解决方案 > SafeMailItem 和 MailItem 的 HTMLBody 属性内容不同

问题描述

撰写新邮件(使用 Outlook 365)时,应在 MailItem 向用户打开之前处理 HTML 正文。为了避免安全警告,我SafeMailItem用来读取HTMLBody属性:

Application outlook = new Application();
MailItem mailItem = outlook.CreateItem(OlItemType.olMailItem);
inspector = mailItem.GetInspector;
SafeMailItem safeMailItem = new SafeMailItem();
safeMailItem.Item = mailItem;

Console.WriteLine("HTMLBody (SafeMailItem): " + Environment.NewLine + safeMailItem.HTMLBody);
Console.WriteLine("HTMLBody (MailItem): " + Environment.NewLine + mailItem.HTMLBody);

// Manipulate HTML body
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(safeMailItem.HTMLBody); // Avoid security warning
HtmlNode firstParagraph = doc.DocumentNode.SelectSingleNode("/html/body//p");
firstParagraph.FirstChild.InnerHtml = "My custom text";
mailItem.HTMLBody = doc.DocumentNode.WriteContentTo(); // Change HTML body of email

mailItem.Display(false);

// Listen to close/send
((InspectorEvents_10_Event)mailItem.GetInspector).Close += MailItem_Close;
outlook.ItemSend += Outlook_ItemSend;

输出是:

HTMLBody (SaveMailItem):
<HTML>
<HEAD><META http-equiv=Content-Type content="text/html; charset=UTF-8"></HEAD>
<BODY>
<!-- Converted from text/plain format -->
</BODY></HTML>

HTMLBody (MailItem):
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta name=ProgId content=Word.Document><meta name=Generator content="Microsoft Word 15"><meta name=Originator content="Microsoft Word 15"><link rel=File-List href="cid:filelist.xml@01D64880.436A9300"><!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><link rel=themeData href="~~themedata~~"><link rel=colorSchemeMapping href="~~colorschememapping~~"><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:TrackMoves/>
<w:TrackFormatting/>
<!-- ... -->

为什么有区别?有没有更好的方法来 1) 创建电子邮件 2) 操作 HTML 正文和 3) 向用户显示电子邮件?

标签: c#outlookoffice-interopoutlook-redemption

解决方案


我终于找到了解决方案

调用后mailItem.GetInspector必须MailItem保存 ( MailItem.Save())。所以完整的工作代码是:

Application outlook = new Application();
MailItem mailItem = outlook.CreateItem(OlItemType.olMailItem);
inspector = mailItem.GetInspector;
mailItem.Save(); // Save mailItem to ensure that HTMLBody can be access from SafeMailItem
SafeMailItem safeMailItem = new SafeMailItem();
safeMailItem.Item = mailItem;

Console.WriteLine("HTMLBody (SafeMailItem): " + Environment.NewLine + safeMailItem.HTMLBody);
Console.WriteLine("HTMLBody (MailItem): " + Environment.NewLine + mailItem.HTMLBody);

// Manipulate HTML body
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(safeMailItem.HTMLBody); // Avoid security warning
HtmlNode firstParagraph = doc.DocumentNode.SelectSingleNode("/html/body//p");
firstParagraph.FirstChild.InnerHtml = "My custom text";
mailItem.HTMLBody = doc.DocumentNode.WriteContentTo(); // Change HTML body of email

mailItem.Display(false);

// Listen to close/send
((InspectorEvents_10_Event)mailItem.GetInspector).Close += MailItem_Close;
outlook.ItemSend += Outlook_ItemSend;

推荐阅读