Issue with TNEF format

Hi,

I need your help with Aspose.Email.dll.

In my scenario I receive messages directly from Exchange Agent (they are EML messages with root part of "application/ms-tnef" content-type). I need to examine the insides of message, make some changes to embedded message (to simplify the topic let’s think that I need to replace all PNG images from all embedded messages with one passed as a parameter) and send it back to Exchange in the same format – EML message with “winmail.data” of "application/ms-tnef" content-type.

Winmail.dat contains all information about main message. The key point here is that all embedded messages are also in TNEF format.

I attached simple message from Exchange: “ExchangeMessage.eml”. Test project is also attached.

Test01

First I tried to read main message with MailMessage class (see Test01 in project). In this case embedded message is automatically converted from TNEF format to .MSG format. You can easily save it to disk (“01_embedded_message.msg”) and open by Outlook. So I read this embedded message; replaced PNGs and saved back to MSG format. Then I changed content stream of embedded message in main message and tried to save main message.

But in this case message is saved without “winmail.dat” – message became “multipart/mixed” – TNEF is not retained (see "01_ ExchangeMessage_SAVE.msg"). Embedded message is saved as MSG attachment.

Then I tried to use other Save-method of MailMessage with FileCompatibilityMode (set to PreserveTnefAttachments). In this case TNEF is preserved, but contains original embedded message, because signature image in embedded message is old.

Test02

Then I tried to use MapiMessage (please see Test02 in project). I got InvalidOperationException with message “This is not a structured storage file.”.

So I manually removed all headers – left only “bare” winmail.dat (“ExchangeMessageOnlyWinmail.dat.eml” file in the project) and tried LoadFromTnef method. Message is successfully read. But I cannot save it back to TNEFSaveAsTnef method throws ArgumentNullException exception “Value cannot be null. Parameter name: data”.

Test03

I also found that MapiMessage.FromProperties method works incorrectly. It shows that embedded message does not have attachments.

But if you save embedded message of main message and use MapiMessage.FromFile – it shows attachments.

<span style=“font-size:11.0pt;line-height:115%;font-family:“Calibri”,“sans-serif”;
mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:“Times New Roman”;
mso-bidi-theme-font:minor-bidi;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA”>So can you please help me find out a way to change
embedded messages and save main message back to the original format?

Thank you,
Alex Shloma
<!–[if gte mso 9]>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>RU</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val=“Cambria Math”/>
<m:brkBin m:val=“before”/>
<m:brkBinSub m:val="–"/>
<m:smallFrac m:val=“off”/>
<m:dispDef/>
<m:lMargin m:val=“0”/>
<m:rMargin m:val=“0”/>
<m:defJc m:val=“centerGroup”/>
<m:wrapIndent m:val=“1440”/>
<m:intLim m:val=“subSup”/>
<m:naryLim m:val=“undOvr”/>
</m:mathPr></w:WordDocument>
<![endif]–><!–[if gte mso 10]>

/* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0in; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-ansi-language:RU;}

<![endif]–>

Hi Alex,

Thank you for contacting Aspose support team.

I would like to share that Aspose.Email provides the feature to create TNEF emails. Following is a sample code which loads a message (say the message in attachment), modify it as required and then saves it as email attachment. Could you please give a try to the following sample code in your scenario and let us know your feedback?

static void TestTnef()
{
//Load the attachment message
MapiMessage msg = MapiMessage.FromFile(@"attachment.msg");

//MODIFY THE MESSAGE HERE LIKE CHANGE IMAGE ETC.

MemoryStream ms = new MemoryStream();
msg.SaveAsTnef(ms);

// Create tnef eml (Its original email in your scenario)
MailMessage eml = new MailMessage("user@gmail.com", "anotheruser@gmail.com");
eml.AddAttachment(new Attachment(ms, "winmail.dat", "application/ms-tnef"));
eml.Save(@"Output.eml", MailMessageSaveType.EmlFormat);
}

Hi Kashif,

Thank you for your answer.

The code above DO saves attached MSG file in TNEF format and attaches it to main message. But if you open original message and output one in text editor and compare them, you will see that

  • Entire original main message is EML message with one MIME root part (application/ms-tnef; name=“winmail.dat”). It means that TNEF part contains main message info, message body (html) and all attachments (embedded messages, regular and inline attchments);
  • “Output.eml” is also EML message, but it is “multipart/mixed” – it contains several MIME parts
    • text/html; charset=“UTF-8” with message body in html format;
    • application/octet-stream; name=“image001.png” with signature image;
    • and one application/ms-tnef; name=“winmail.dat” which contains only one embedded message in TNEF format

And it means that:

  • We lost all information about main message (“ExchangeMessage.eml”) which were in TNEF part:
    • SearchKey, Priority (Importance), DateSent, DateModified, RecipientTable, MapiProperties (SentRepresentingName, SenderName, SendRichInfo, AlternateRecipientAllowed, MessageClass, OriginatorDeliveryReportRequested, ReadReceiptRequested, Sensitivity, ClientSubmitTime, StoreSupportMask, DdbProvider…).
  • Your code supposes that 2 winmail.dat will be added if main message contains 2 embedded messages.
  • Message formats are not identical.

Best regards,

Alex Shloma

Hi Alex,


After further investigating this issue at my end using the latest version of Aspose.Email for .NET 3.8.0, I was able to observe the issue as mentioned in your sample code. The PreserveTnefAttachments should have saved the modified embedded image in the attached MSG file. I have logged it as NETWORKNET-34266 in our issue tracking system and will update you here once there is some information or fix version available in this regard.

We regret the inconvenience caused to you in this regard.

The issues you have found earlier (filed as NETWORKNET-34266) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by Aspose Notifier.

Will check and let you know

Thank you,

Alex Shloma

Hi,

I’ve tested your fix. It seems that “FileCompatibilityMode.PreserveTnefAttachments” works now.

But still there is an issue reading MapiMessage from properties (see Test03 method in test project). MapiMessage read by means of FromProperties does not show attachments (collection of attachments is empty). Bu if I save attachment of main message to file and then read it with FromFile, then collection of attachments contains 2 objects.

Thank you,

Alex Shloma

Hi Alex,


Thank you for sharing the feedback.

I was able to observe the issue using the latest version of Aspose.Email for .NET 4.0.0 and have logged the findings against issue id: NETWORKNET-34322. We’ll update you here once any feedback is available and appreciate your patience in this regard.

Hi Alex,


We are glad to share that new version Aspose.Email for .NET 4.1.0 is released and available for download.

I would like to share that information about attachments and recipients cannot be retrieved from Properties of MapiMessage. Following is a sample code which demonstrates the method to extract the required information. Could you please give it a try and let us know your feedback using above mentioned latest version?

string fileName = Path.Combine(“ExchangeMessageOnlyWinmail.dat.eml”);
MapiMessage originalMapiMessage = MapiMessage.LoadFromTnef(fileName);
MapiMessage attMsg = null;
if (originalMapiMessage.Attachments[0].ObjectData.IsOutlookMessage)
{
attMsg = MapiMessage.FromStream(new MemoryStream(originalMapiMessage.Attachments[0].ObjectData.Data));
Console.WriteLine(attMsg.Attachments.Count);//It should display 2
}

Could you please move this ticket to Priority Support forum?

Thanks in advance,

Alex Shloma

Hi Alex,


This issue has already been investigated and the above provided code snippet can be used to get the correct results. Hence, there is no need to re-open or move this ticket to priority support. If you have any other query/inquiry related to Aspose.Email, please feel free to write to us.