Различение встроенных и обычных вложений

Это распространенный сценарий, когда электронное сообщение может содержать встроенные изображения в своем теле, а также обычные вложения, связанные с ним. Используя класс MailMessage, встроенные вложения можно извлечь из класса LinkedResourceCollection, тогда как обычные вложения можно получить/извлечь с помощью класса AttachmentCollection сообщения. Однако это отличается, когда сообщение загружается с использованием класса Aspose.Email.Mapi.MapiMessage, так как все встроенные изображения и обычные вложения доступны пользователю в одном и том же классе MapiAttachmentCollection. Следовательно, необходимо разработать метод, который сможет различать встроенные и обычные вложения, когда используется MapiMessage.

Использование Aspose.Email для различения встроенных и обычных вложений

Эта статья объясняет, как различать встроенные вложения от обычных с использованием MapiMessage. Чтобы определить это различие, учитывается тип тела MapiMessage следующим образом:

Тело в простом тексте: Электронные сообщения с телом в простом тексте не нужно проверять, так как все вложения в таких сообщениях всегда являются обычными вложениями.

Html Тело: В случае сообщения с телом HTML, вложение должно не только содержать свойство PR_ATTACH_FLAGS (0x37140003), но также его значение должно быть равно 0x00000004 для встроенных вложений. Если это условие выполнено, то все зависит от тегов PR_ATTACH_CONTENT_LOCATION и PR_ATTACH_CONTENT_ID для определения природы вложения. Однако при отсутствии тега Mapi PR_ATTACH_FLAGS вложение проверяется по свойству PR_ATTACH_DISPOSITION (0x3716001F или 0x3716001E), чтобы определить тип вложения.

Rtf Тело: Если тело является RTF, то все OLE-вложения являются встроенными вложениями. Значение PR_ATTACH_METHOD для всех OLE-вложений равно 0x00000006.

Следующий пример кода демонстрирует, как программно различать встроенные и обычные вложения. Функция IsInlineAttachment принимает вложение и тип тела сообщения в качестве входных параметров и возвращает true, если вложение является встроенным.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
public static void Run()
{
string dataDir = RunExamples.GetDataDir_Email();
var message = MapiMessage.FromFile(dataDir + "RemoveAttachments.msg");
var attachments = message.Attachments;
var count = attachments.Count;
Console.WriteLine("Total attachments " + count);
for (int i = 0; i < attachments.Count; i++)
{
var attachment = attachments[i];
if (IsInlineAttachment(attachment, message))
{
Console.WriteLine(attachment.LongFileName + " is inline attachment");
}
else
{
Console.WriteLine(attachment.LongFileName + " is regular attachment");
}
}
}
public static bool IsInlineAttachment(MapiAttachment att, MapiMessage msg)
{
switch (msg.BodyType)
{
case BodyContentType.PlainText:
// ignore indications for plain text messages
return false;
case BodyContentType.Html:
// check the PidTagAttachFlags property
if (att.Properties.ContainsKey(0x37140003))
{
long? attachFlagsValue = att.GetPropertyLong(0x37140003);
if (attachFlagsValue != null && (attachFlagsValue & 0x00000004) == 0x00000004)
{
// check PidTagAttachContentId property
if (att.Properties.ContainsKey(MapiPropertyTag.PR_ATTACH_CONTENT_ID) ||
att.Properties.ContainsKey(MapiPropertyTag.PR_ATTACH_CONTENT_ID_W))
{
string contentId = att.Properties.ContainsKey(MapiPropertyTag.PR_ATTACH_CONTENT_ID)
? att.Properties[MapiPropertyTag.PR_ATTACH_CONTENT_ID].GetString()
: att.Properties[MapiPropertyTag.PR_ATTACH_CONTENT_ID_W].GetString();
if (msg.BodyHtml.Contains(contentId))
{
return true;
}
}
// check PidTagAttachContentLocation property
if (att.Properties.ContainsKey(0x3713001E) ||
att.Properties.ContainsKey(0x3713001F))
{
return true;
}
}
else if ((att.Properties.ContainsKey(0x3716001F) && att.GetPropertyString(0x3716001F) == "inline")
|| (att.Properties.ContainsKey(0x3716001E) && att.GetPropertyString(0x3716001E) == "inline"))
{
return true;
}
}
else if ((att.Properties.ContainsKey(0x3716001F) && att.GetPropertyString(0x3716001F) == "inline")
|| (att.Properties.ContainsKey(0x3716001E) && att.GetPropertyString(0x3716001E) == "inline"))
{
return true;
}
return false;
case BodyContentType.Rtf:
// If the body is RTF, then all OLE attachments are inline attachments.
// OLE attachments have 0x00000006 for the value of the PidTagAttachMethod property
if (att.Properties.ContainsKey(MapiPropertyTag.PR_ATTACH_METHOD))
{
return att.GetPropertyLong(MapiPropertyTag.PR_ATTACH_METHOD) == 0x00000006;
}
return false;
default:
throw new ArgumentOutOfRangeException();
}
}