Folder.UpdateMessage(entryId, message)replaces the existing message in the PST folder with the MapiMessage you pass in.
It does not merge the new message with the old one – everything that is not present in the supplied MapiMessage (including embedded messages, inline images, custom properties, etc.) will be lost.
In your sample you:
inbox[1].DeleteChildItems([ids[0]]); // ❌ removes the original message
// inbox[1].UpdateMessage(ids[0], msg); // now you try to update a non‑existent entry
inbox[1].AddMessage(msg); // adds a brand‑new message
The call to DeleteChildItems deletes the original message before you try to update it.
UpdateMessage then works on a stale entryId, which produces the “weird results” you see.
What you need to do
Do not delete the message if you intend to update it.
If you need to keep the original embedded messages (or any other attachments), copy them from the existing message into the new one before calling UpdateMessage.
Below is a typical pattern for updating a message while preserving its embedded items.
Step‑by‑Step Solution
using Aspose.Email;
using Aspose.Email.Mapi;
using Aspose.Email.Storage.Pst;
// ---------- 1. Load PST ----------
PersonalStorage pst = PersonalStorage.FromFile(pstFilePath);
MapiFolder inbox = pst.RootFolder.GetSubFolder("Inbox");
// ---------- 2. Locate the message ----------
string entryId = inbox.EnumerateMessagesEntryId().First(); // example: first message
// ---------- 3. Load the *existing* message ----------
MapiMessage originalMsg = inbox.GetMessage(entryId);
// ---------- 4. Create / modify the new message ----------
MapiMessage newMsg = MapiMessage.FromMailMessage(MailMessage.Load(emlFilePath));
// ---- 4a. Preserve embedded messages / attachments ----
foreach (MapiAttachment att in originalMsg.Attachments)
{
// Keep only the embedded messages (type = MapiAttachmentType.EmbeddedMessage)
// or any other attachment you want to retain.
if (att.Type == MapiAttachmentType.EmbeddedMessage ||
att.IsInline ||
att.IsEmbeddedMessage)
{
newMsg.Attachments.Add(att);
}
}
// You can also copy custom properties, conversation index, etc.
newMsg.ConversationIndex = originalMsg.ConversationIndex;
newMsg.Subject = newMsg.Subject; // or modify as required
// ---------- 5. Update the message ----------
inbox.UpdateMessage(entryId, newMsg);
Key Points
What you want
How to achieve it
Update an existing item
Use UpdateMessage(entryId, newMsg). Do not delete the item first.
Keep embedded messages/attachments
Load the existing MapiMessage, copy the needed MapiAttachments into the new one, then call UpdateMessage.
Preserve custom MAPI properties
After creating newMsg, copy any required properties: newMsg.SetProperty(propertyTag, originalMsg.GetProperty(propertyTag));
Change only body or subject
Load the original message, modify newMsg.Body / newMsg.Subject, then UpdateMessage. No need to touch attachments.
Common Pitfalls & How to Avoid Them
Pitfall
Why it happens
Fix
Calling DeleteChildItems before UpdateMessage
The entry ID no longer refers to a valid message, so ASPose replaces it with a minimal placeholder.
Remove the delete call; let UpdateMessage overwrite the message in place.
Using MapiMessage.FromMailMessage on an EML that contains embedded messages
The conversion strips out message/rfc822 attachments because they are treated as regular attachments.
Load the original PST message, copy its Attachments collection, then add any new content.
Losing custom properties (PR_ tags)*
FromMailMessage creates a fresh MapiMessage without the custom tags.
After creating newMsg, copy the needed properties from originalMsg as shown above.
Expecting UpdateMessage to merge bodies
UpdateMessage replaces the entire message object.
Build the final MapiMessage exactly as you want it (merge bodies manually if needed).
We are sorry if we confused you with our code snippet, we were trying multiple things and just realized we provided you with an incorrect code snippet. Please find the correct code snippet below.
using Aspose.Email;
using Aspose.Email.Mapi;
using Aspose.Email.Storage.Pst;
var asposeLicense = new License();
var pstFilePath = args[0];
var emlFilePath = args[1];
var asposeLicensePath = args[2];
SetAsposeLicense();
using var pst = PersonalStorage.FromFile(pstFilePath);
var inbox = pst.RootFolder.EnumerateFolders(FolderKind.Normal).ToArray();
var msg = MapiMessage.FromMailMessage(MailMessage.Load(emlFilePath));
var ids = inbox[1].EnumerateMessagesEntryId().ToArray();
I’ve checked with our developers, and they were able to reproduce the problem where UpdateMessage removes embedded messages.
A ticket has been created for further investigation and resolution.
Thank you. Do you have any estimates when we can have a fix for this? this is a high priority and it is a customer requirement that we will need a fix asap as we will loose the customer if this is not fixed.