电子邮件消息中的 TNEF 附件处理
**TNEF(传输中性封装格式)**是 Microsoft Outlook 用于在附件中封装丰富内容的专有格式,最常存储为 winmail.dat。Aspose.Email API 允许您读取包含 TNEF 附件的电子邮件并修改附件内容。然后可以将电子邮件保存为普通邮件或相同格式,保留 TNEF 附件。本文展示了处理包含 TNEF 附件的消息的不同代码示例。本文还展示了如何从 Outlook MSG 文件创建 TNEF EML 文件。
读取含 TNEF 附件的消息
以下代码片段展示了如何读取保留 TNEF 附件的消息。
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Email();
MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = true;
MailMessage eml = MailMessage.Load(dataDir + "EmbeddedImage1.msg", options);
foreach (Attachment attachment in eml.Attachments)
{
Console.WriteLine(attachment.Name);
}
读取不含 TNEF 附件的消息
下面的代码片段演示了如何读取消息而不保留 TNEF 附件。设置 PreserveTnefAttachments 设置为 false 是默认行为:TNEF 容器被解码,其内容被作为普通附件暴露,而不是单个 winmail.dat 文件。
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Email();
MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = false;
MailMessage eml = MailMessage.Load(dataDir + "EmbeddedImage1.msg", options);
foreach (Attachment attachment in eml.Attachments)
{
Console.WriteLine(attachment.Name);
}
加载和保存 TNEF 附件
使用 Aspose.Email for .NET,您可以直接将 TNEF 附件加载到 MapiAttachment 使用文件路径或流来获取对象,然后将对象保存为 TNEF 格式。这使得能够创建 winmail.dat 文件或在电子邮件工作流中保留 Outlook 特有的格式。
API 在以下成员中提供 MapiAttachment 类:
加载 TNEF 附件
-
static MapiAttachment LoadFromTnef(string fileName) - 从 .dat 文件加载 TNEF 附件。
-
static MapiAttachment LoadFromTnef(Stream stream) - 从流(例如 MemoryStream 或文件流)加载 TNEF 附件。
保存 TNEF 附件
-
void SaveToTnef(string filename) - 将 MapiAttachment 保存为 TNEF 文件。
-
void SaveToTnef(Stream stream) - 将 MapiAttachment 以 TNEF 格式保存到流中。
下面的代码示例演示了如何从电子邮件中提取 winmail.dat 附件,保留它,并将其重新添加为消息的附件:
// message.eml contains a winmail.dat attachment, but by default, the attachment is not preserved.
var msg = MapiMessage.Load("message.eml");
// Save the attachment to TNEF format in a stream and load it back
var ms = new MemoryStream();
msg.Attachments[0].SaveToTnef(ms);
ms.Position = 0;
var fromTnefAttachment = MapiAttachment.LoadFromTnef(ms);
msg.Attachments.Add(fromTnefAttachment);
// The same can be done through a file
msg.Attachments[0].SaveToTnef("winmail.dat");
fromTnefAttachment = MapiAttachment.LoadFromTnef("winmail.dat");
msg.Attachments.Add(fromTnefAttachment);
更新 TNEF 附件中的资源
以下代码片段展示了如何在 TNEF 附件中更新资源并保留 TNEF 格式。
public static void TestUpdateResources(string dataDir)
{
string fileName = dataDir + "tnefEML1.eml";
string imgFileName = dataDir + "Untitled.jpg";
string outFileName = dataDir + "UpdateTNEFAttachments_out.eml";
MailMessage originalMailMessage = MailMessage.Load(fileName);
UpdateResources(originalMailMessage, imgFileName);
EmlSaveOptions emlSo = new EmlSaveOptions(MailMessageSaveType.EmlFormat);
emlSo.FileCompatibilityMode = FileCompatibilityMode.PreserveTnefAttachments;
originalMailMessage.Save(outFileName, emlSo);
}
private static void UpdateResources(MailMessage msg, string imgFileName)
{
for (int i = 0; i < msg.Attachments.Count; i++)
{
if ((msg.Attachments[i].ContentType.MediaType == "image/png") || (msg.Attachments[i].ContentType.MediaType == "application/octet-stream" && Path.GetExtension(msg.Attachments[i].ContentType.Name) == ".jpg"))
{
msg.Attachments[i].ContentStream = new MemoryStream(File.ReadAllBytes(imgFileName));
}
else if ((msg.Attachments[i].ContentType.MediaType == "message/rfc822") || (msg.Attachments[i].ContentType.MediaType == "application/octet-stream" && Path.GetExtension(msg.Attachments[i].ContentType.Name) == ".msg"))
{
MemoryStream ms = new MemoryStream();
msg.Attachments[i].Save(ms);
ms.Position = 0;
MailMessage embeddedMessage = MailMessage.Load(ms);
UpdateResources(embeddedMessage, imgFileName);
MemoryStream msProcessedEmbedded = new MemoryStream();
embeddedMessage.Save(msProcessedEmbedded, SaveOptions.DefaultMsgUnicode);
msProcessedEmbedded.Position = 0;
msg.Attachments[i].ContentStream = msProcessedEmbedded;
}
}
foreach (LinkedResource att in msg.LinkedResources)
{
if (att.ContentType.MediaType == "image/png")
att.ContentStream = new MemoryStream(File.ReadAllBytes(imgFileName));
}
}
向 TNEF 消息添加附件
以下代码片段展示了如何向包含 TNEF 的主消息添加新附件。
string fileName = "MainMessage.eml";
string attachName = "s.png";
string outFileName = "test.eml";
MailMessage mailMessage = MailMessage.Load(fileName);
mailMessage.Attachments.Add(new Attachment(File.OpenRead(attachName), "s.png", "image/png"));
// The TNEF content of the original message is preserved via EmlSaveOptions
EmlSaveOptions emlSaveOptions = new EmlSaveOptions(MailMessageSaveType.EmlFormat)
{
FileCompatibilityMode = FileCompatibilityMode.PreserveTnefAttachments
};
mailMessage.Save(outFileName, emlSaveOptions);
从 MSG 创建 TNEF EML
Outlook MSG 有时包含表格和文本样式等信息,如果直接转换为 EML 可能会被破坏。从此类 MSG 文件创建 TNEF 消息可以保留格式,甚至通过电子邮件客户端发送时保持格式。 MailConversionOptions.ConvertAsTnef 属性用于实现此功能。以下代码片段展示了如何从 MSG 创建 TNEF EML。
MapiMessage mapiMsg = MapiMessage.FromFile(dataDir + "Message.msg");
MailConversionOptions mco = new MailConversionOptions();
mco.ConvertAsTnef = true;
MailMessage message = mapiMsg.ToMailMessage(mco);
或者,也可以通过使用 PreserveTnefAttachments 选项属于 MsgLoadOptions 类已启用,然后将结果保存为 EML。
// Loading the MSG with PreserveTnefAttachments will create the TNEF eml.
MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = true;
MailMessage eml = MailMessage.Load(msgFileName, options);
eml.Save(emlFileName, SaveOptions.DefaultEml);
识别 TNEF 格式的消息
以下代码片段展示了如何检测消息是否为 TNEF。
MailMessage mail = MailMessage.Load(dataDir + "tnefEml1.eml");
bool isTnef = mail.OriginalIsTnef;
Console.WriteLine("Is input EML originally TNEF? {0}", isTnef.ToString());
识别 TNEF 格式的附件
该 Attachment.IsTnef 属性用于检测附件是否为 TNEF 格式的消息。
var eml = MailMessage.Load(fileName);
foreach (var attachment in eml.Attachments)
{
Console.WriteLine($"Is Attachment TNEF?: {attachment.IsTnef}");
}