2 bugs in attachment class

Hello,
Let me make sure I understood you correctly, you mean Aspose Email will not be able to save the RTF body of a msg email as RTF?!

@australian.dev.nerds

To get the inline MapiAttachment, please check the code example in following article.
Identify and Extract embedded attachment from MSG formatted as RTF

You can use MapiAttachment.BinaryData.Length property to get the size of attachment.

Please check IsAttachmentInline method from here.

Please also read the following article.
Differentiating between Inline and Regular Attachments

MapiAttachment.DisplayName returns the display name of OLE object in an attachment. However, the MapiAttachment.FileName property returns base filename and extension.

The MapiAttachment.FileName and MapiAttachment.LongFileName properties represent PidTagAttachFilename and PidTagAttachLongFilename MAPI properties respectively.

MapiAttachment.FileName: “The file name is restricted to eight characters plus a three-character extension.”
MapiAttachment.LongFileName: “it can be up to 256 characters long, including the filename, extension, and separator period.”

For Windows platform you should use the LongFileName property as suggested file name for saving an attachment.

We have logged a ticket for this issue as EMAILNET-40886 in our issue tracking system. We will inform you once this issue is resolved. We apologize for your inconvenience.

@australian.dev.nerds

You can use MapiMessage.BodyRtf property to get RTF formatted message text. However, you cannot import the RTF content using MapiMessage.Load.

Please share the message file for which the RTF content are corrupted. We will investigate the issue and then log it for fix.

1 Like

@australian.dev.nerds

Please check my reply about MapiAttachment.IsInline from here:

Hi,
Of course I don’t want to import/Load the RTF to Aspose Email…
I’m just trying to save the RTF part of OLE2 messages loaded into MailMessage/MapiMessage as .rtf from MapiMessage.BodyRtf property using this:

File.WriteAllText(“D:\richbody.rtf”, MyMapiMessage.BodyRtf, Encoding.UTF8)

Is my usage correct or there’s another built-in method to save msg body as RTF?

If so, there should be an issue here, run the sample, inside the Release folder there’s msg.msg.
It will load it to save the RTF Body as richbody.rtf
Check the output richbody.rtf file, it’s ALWAYS deformed, you can try any other MSG.
Thanks.
WindowsApplication2.zip (23.2 KB)

@australian.dev.nerds

Please note that this issue is not related to Aspose.Email. If you save the RTF to TXT file format using File.WriteAllText and save the TXT to RTF using notepad, you will get the correct output.

You may use Encoding.Default encoding as shown below to avoid this issue.

File.WriteAllText(My.Application.Info.DirectoryPath + "\richbody.rtf", MyMapiMessage.BodyRtf.Trim(), System.Text.Encoding.Default)
1 Like

Thanks for the tip, sorry my bad, and also can use it without the encoding parameter right?

File.WriteAllText(outFile, MapiMessage.BodyRtf)

Anyway still having one issue and one question in this regard:

Issue: RTF supports embedding images, I mean even in Windows Wordpad we can insert images into our RTF document, so should I expect to have the images saved in the RTF file created? Because I don’t have them!

Question: When saving:
File.WriteAllText(outFile, MapiMessage.BodyHtml)
or
File.WriteAllText(outFile, MapiMessage.Body) 'PlainText
Shall I specify the encoding parameter or the same RTF, should not?
Best :slight_smile:

@australian.dev.nerds

Yes, the images will be exported to RTF.

It depends on your requirements. If the content of output RTF needs encoding, you can use it in File.WriteAllText method.

I’m afraid it’s not!
WindowsApplication3.zip (2.9 MB)
Simply run the sample to save MSG body’s RTF and you’ll see the images are not saved!

@australian.dev.nerds

We have logged this problem in our issue tracking system as EMAILNET-40891. You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

1 Like

Where are these properties of MapiAttachment?

MapiAttachment.ContentStream
MapiAttachment.ContentType
MapiAttachment.IsEmbeddedMessage
MapiAttachment.IsUri

How about syncing MapiAttachment and MailMessage.Attachment properties?

@australian.dev.nerds

We have logged this feature request as EMAILNET-40893 in our issue tracking system. You will be informed once there is an update available on it.

1 Like

Extension | Aspose.Email for .NET API Reference

MapiAttachment.Extension will get the extension based on which property?
DisplayName? FileName? LongFileName?
I it will loop and try to get it from any available property? or jus one of the above is tried?
Thanks :slight_smile:

@australian.dev.nerds

Unfortunately, your requirement is not clear enough. Please share some more detail about it. We will then provide you more information on it.

@australian.dev.nerds

Regarding EMAILNET-40886, we have fixed this issue.

Please note that attachments that are shared in the images were not damaged but saved in msg format instead of .eml (You can change extension of files on msg and try to open in Outlook). This is not a bug, but a feature of Aspose.Email. If the message is loaded into MapiMessage then the attachments are converted to msg format. To keep the original format (EML in our case) use the setting PreserveEmbeddedMessageFormat of LoadOptions as shown in the code example below.
2.In the MSG format DisplayName and Extension of attachment are stored in different properties, so when saving an attachment, you need to use LongFileName instead of DisplayName .

Aspos.Email had problems with names and extensions when converting EML>MSG and vice versa. These issues are fixed as part of this ticket, the fixes will be available in the next release subject to the notes above.

        private static void ProcessAttachment(MapiAttachment mapiAttach)
        {
            mapiAttach.Save(mapiAttach.LongFileName);

            if (mapiAttach.BinaryData != null && mapiAttach.BinaryData.Length > 0)
            {
                MapiMessage message = null;
                MemoryStream ms = new MemoryStream(mapiAttach.BinaryData);
                FileFormatInfo info = FileFormatUtil.DetectFileFormat(ms);
                ms.Position = 0;
                switch (info.FileFormatType)
                {
                    case FileFormatType.Msg:
                    case FileFormatType.Oft:
                        message = MapiMessage.Load(ms, new MsgLoadOptions(){PreserveEmbeddedMessageFormat = true});
                        break;
                    case FileFormatType.Eml:
                        message = MapiMessage.Load(ms, new EmlLoadOptions(){PreserveEmbeddedMessageFormat = true});
                        break;
                    case FileFormatType.Mht:
                        message = MapiMessage.Load(ms, new MhtmlLoadOptions());
                        break;
                    case FileFormatType.Emlx:
                        message = MapiMessage.Load(ms, new EmlxLoadOptions());
                        break;
                    case FileFormatType.Tnef:
                        message = MapiMessage.LoadFromTnef(ms);
                        break;
                }
                if (message != null)
                {
                    foreach (MapiAttachment innerAttach in message.Attachments)
                    {
                        ProcessAttachment(innerAttach);
                    }
                }
            }
        }
1 Like

Hi, great to see 40886 is fixed, today or tomorrow will be public? :slight_smile:

@australian.dev.nerds

Hopefully, the next version of Aspose.Email will be available on 30 or 31 December 2022.

@australian.dev.nerds

Hello
RTF content and embedded images are stored in different properties in MSG format. Therefore, we think that embedding images inside RTF is not the responsibility of Aspose.Email. To achieve the desired result, you can use Aspose.Words, see sample code below.

        string fileName = "msg.msg";
        MailMessage message = MailMessage.Load(fileName);
        MemoryStream ms = new MemoryStream();
        message.Save(ms, SaveOptions.DefaultMhtml);
        Aspose.Words.Loading.LoadOptions opt = new Aspose.Words.Loading.LoadOptions();
        opt.LoadFormat = Aspose.Words.LoadFormat.Mhtml;
        Aspose.Words.Document doc = new Aspose.Words.Document(ms, opt);
        doc.Save(fileName + ".rtf", Aspose.Words.SaveFormat.Rtf);
1 Like

Hello and thanks for your kind help, I appreciate the solution and will consider it for future possible usage.
But currently, it’s not wise to add a 2nd DLL due to the size and the fact that I’m very limited from adding additional DLLs to the solution, specially for such minor task: just to save message body.
The licensing and pricing would be another preventing issue, although if this option can embed in Aspose.Email so users won’t need to add Aspose.Words for an extra reasonable charge, seems wise to me.
But adding the whole Words.dll which is also big in size and get the full license just for saving message body seems not suitable for most users.
Just my thought though… :slight_smile:

oops, and looking the code (not tested yet) it seems that you’re saving the message as RFC822 EML/MHTML and then convert the produced mhtml with embedded images to RTF.
I mean you’re not directly accessing the source message’s RTF body to process it and save it as RTF.
In my usage, my source message always has RTF body part, but might not have html/text part, so no idea what happens then, and even if it works, it’s definitely not the best because converting RTF to HTML and converting back to RTF never makes the identical results as source! No one ever made such complex converter that works that I’m aware of!

Challenge? Test this message:
Stationary.zip (889.4 KB)