Diferenciando entre Anexos Inline e Regulares

É um cenário comum quando uma mensagem de email pode conter imagens inline dentro de seu corpo, bem como anexos regulares associados a ela. Usando a classe MailMessage, os anexos inline podem ser extraídos da classe LinkedResourceCollection, enquanto os anexos regulares podem ser acessados/extrados com a classe AttachmentCollection de uma mensagem. No entanto, isso é diferente quando a mensagem é carregada usando a classe Aspose.Email.Mapi.MapiMessage, pois todas as imagens inline e anexos regulares são acessíveis ao usuário na mesma classe MapiAttachmentCollection. Portanto, é necessário desenvolver um método que possa diferenciar entre um anexo inline e um anexo regular quando o MapiMessage é utilizado.

Usando Aspose.Email para Diferenciar entre Anexos Inline e Regulares

Este artigo explica como diferenciar anexos inline de anexos regulares usando o MapiMessage. Para determinar essa diferenciação, o tipo de corpo do MapiMessage é considerado da seguinte forma:

Corpo de Texto Simples: Mensagens de email com tipo de corpo de texto simples não precisam ser verificadas, pois todos os anexos nessas mensagens são sempre anexos regulares.

Corpo HTML: No caso de uma mensagem com tipo de corpo HTML, o anexo não deve apenas conter a propriedade PR_ATTACH_FLAGS (0x37140003), mas também seu valor deve ser igual a 0x00000004 para anexos inline. Se essa condição for atendida, então depende ainda das Tags PR_ATTACH_CONTENT_LOCATION e PR_ATTACH_CONTENT_ID para determinar a natureza do anexo. No entanto, na ausência da tag Mapi PR_ATTACH_FLAGS, o anexo é verificado quanto à propriedade PR_ATTACH_DISPOSITION (0x3716001F ou 0x3716001E) para determinar o tipo de anexo.

Corpo Rtf: Se o corpo for RTF, então todos os anexos OLE são anexos inline. O valor de PR_ATTACH_METHOD para todos os anexos OLE é igual a 0x00000006.

O seguinte exemplo de código demonstra como diferenciar programaticamente entre anexos inline e regulares. A função IsInlineAttachment leva um anexo e o tipo de corpo da mensagem como parâmetros de entrada e retorna verdadeiro se o anexo for um anexo inline.

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