Aspose not differentiating between attachments correctly

I am implementing some validation logic for an in-house application. The validation logic has to check if all of an emails attachments are PDFs and if they are then perform some action on them. I have been using the IsInlineAttachment method to discriminate between in-line and non in-line attachments. However I have come across an email which has an image attachment that is not identified as an in-line attachment but doesn’t appear in the attachments list in outlook either. I was wondering how I would go about identifying attachments like this?

Thanks,

@dev_net,

Please share your sample message file with us for further investigation at our end.

Thanks, I have PM’d you the file.

@dev_net,

I have opened “FW Another test.msg” in a third party tool MFCMapi.exe and observed its properties. It contains 6 attachments as per this tool. This message was also loaded into MapiMessage using Aspose.Email and it is observed that number of attachments is same i.e. 6 out of which 2 are inline. This message is opened in Outlook and two inline images can be seen there as well.

Hence no issue is observed and attachments are detected properly. Please give a try to the following sample code and share the feedback.

var message = MapiMessage.FromFile("FW Another test.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();
    }
}

Thanks for looking at this issue, my question is this: There are attachments on the email that are not in-line and yet don’t appear as normal attachments on the email when I view it in Outlook. How do I filter the emails attachments to retrieve only attachments that would appear as attachments when the email is opened in outlook?

Cheers,

@dev_net,

The previous sample file which was provided to us by you was analysed but no issue was observed while comparing with Outlook. It all depends on the properties which are available in the message and above mentioned sample code can be used to differentiate the inline and normal attachments. If you have any sample message which contains both inline and normal attachments, but Aspose is not able to differentiate them properly in comparison to Outlook, then please send us the sample message. We will investigate it and provide assistance accordingly. Till now we have found above mentioned function working fine to differentiate the inline and normal attachments.

TestMessage.zip (98.9 KB)

image.png (5.2 KB)

Hi Again,

I have attached another .msg file that illustrates the problem. When you open the email in outlook there are no attachments. There are five attachments in the attachments collection for this file when opened using MapiMessage.FromFile. Four of these attachments are identified as inline attachments. The fifth attachment (see above image.png) is not identified as an in-line attachment. Given that this image is in the attachments collection and does not appear as an attachment within outlook should this image be identified as an in-line attachment?

Thanks,

@dev_net,

I have checked the sample TestMessage.msg file and observed the issue. It is logged under Id:EMAILNET-38999 for detailed analysis later. You will be automatically notified once any update is ready to share.

Hello,
I am facing the same issue. Please can you share the ticket resolution details?
I paste a debug for the isInLineAttachment method where the “non-expected” image is identified with a contentId but not found in bodyHtml (as expected as is not part of the mail content)
image.png (102,2 KB)

Hi @alvarig
Could you please share the original message file so that we can investigate the issue on our side?

Hello, thanks for the support! Just sent the message in private

Hi @alvarig
Thanks for the message, we will look into your issue and get back to you soon.

1 Like

Hi @alvarig
It is not a bug of AE.
This is a special case, which was discussed earlier.

The MapiMessage attachment contains the MapiPropertyTag.PR_ATTACH_CONTENT_ID_W tag, so Outlook determines as “not regular” and does not dispayed in attachments list.
On the other hand, method IsInlineAttachment checks whether the HtmlBody contains reference to an attachment and it is not determined as inline if reference is not found in the HtmlBody.

So if you need to get a list of inline images you can use IsInlineAttachment without changes, if you need to get a list of “not regular” attachments you should exclude checking the reference in HtmlBody.