Not able to update mails within pst files

Hello Team,
We have a requirement from one of our cliet where we need to edit and encrypt mails saved within .pst files.
I tried trial aspose package and I am unable to edit subject, content/body and attachment. I tried below code and it works only at first time. From second time onwards. I am start getting error.

Error:
System.ArgumentException: ‘An item with the same key has already been added. Key: 0’

Sample Code .NET 6 / 8.

                    MapiPropertyCollection keyValuePairs = new MapiPropertyCollection();
                    keyValuePairs.Add(MapiPropertyTag.PR_SUBJECT_W, new MapiProperty(MapiPropertyTag.PR_SUBJECT_W, Encoding.Unicode.GetBytes(updatedSubject)));

                    if(message.BodyType == BodyContentType.Html)
                    {
                        keyValuePairs.Add(MapiPropertyTag.PR_BODY_HTML, new MapiProperty(MapiPropertyTag.PR_BODY_HTML, Encoding.Unicode.GetBytes(message.BodyHtml.Replace("amit","Amit Singh Rawat"))));
                    }
                    else if (message.BodyType == BodyContentType.PlainText)
                    {
                        keyValuePairs.Add(MapiPropertyTag.PR_BODY_HTML, new MapiProperty(MapiPropertyTag.PR_BODY, Encoding.Unicode.GetBytes(message.Body.Replace("amit", "Amit Singh Rawat"))));
                    }
                    //Need to check with RTF Message body is

                    IList<string> changeList = [entryIdBase64];

;

                    inbox.ChangeMessages(changeList, keyValuePairs);

@asrank1008

It seems you are encountering an issue when trying to update emails within PST files using Aspose.Email. The error message you are receiving, “An item with the same key has already been added. Key: 0,” typically indicates that you are attempting to add a property to the MapiPropertyCollection that already exists.

To resolve this issue, you should ensure that you are not adding the same property multiple times. Here’s a modified version of your code that checks if the property already exists before adding it:

MapiPropertyCollection keyValuePairs = new MapiPropertyCollection();

// Update subject
if (!keyValuePairs.Contains(MapiPropertyTag.PR_SUBJECT_W))
{
    keyValuePairs.Add(MapiPropertyTag.PR_SUBJECT_W, new MapiProperty(MapiPropertyTag.PR_SUBJECT_W, Encoding.Unicode.GetBytes(updatedSubject)));
}

// Update body based on content type
if (message.BodyType == BodyContentType.Html)
{
    if (!keyValuePairs.Contains(MapiPropertyTag.PR_BODY_HTML))
    {
        keyValuePairs.Add(MapiPropertyTag.PR_BODY_HTML, new MapiProperty(MapiPropertyTag.PR_BODY_HTML, Encoding.Unicode.GetBytes(message.BodyHtml.Replace("amit", "Amit Singh Rawat"))));
    }
}
else if (message.BodyType == BodyContentType.PlainText)
{
    if (!keyValuePairs.Contains(MapiPropertyTag.PR_BODY))
    {
        keyValuePairs.Add(MapiPropertyTag.PR_BODY, new MapiProperty(MapiPropertyTag.PR_BODY, Encoding.Unicode.GetBytes(message.Body.Replace("amit", "Amit Singh Rawat"))));
    }
}

// Prepare the list of message entry IDs to change
IList<string> changeList = new List<string> { entryIdBase64 };

// Update messages
inbox.ChangeMessages(changeList, keyValuePairs);

In this code, before adding a property to keyValuePairs, it checks if that property already exists using the Contains method. This should help prevent the ArgumentException you are experiencing.

If you continue to face issues, please ensure that the entryIdBase64 is valid and corresponds to the messages you are trying to update. Additionally, consider checking if the PST file is not corrupted, as this can also lead to unexpected behavior.

For further reference, you can look at examples of updating messages in PST files provided in the Aspose documentation and GitHub repositories, which demonstrate similar operations [1][2].

Sources:
[1]: UpdateBulkMessagesInPSTFile.cs
[2]: UpdateMessagePropertiesInPSTFile.java

I believe the check should be on “message.Properties.Keys” instead of KeyValutPair. I tried with both But is not working. Doesn’t matter which Property I add, on the second attempt onward. I keep on getting this error.

FYI, I am not using the paid version.

Also, I want to update messages, content and attachment. There may be instances where I need to update messages twice or even more frequently. Is this possible with ASPOSE .NET?

Hi @asrank1008
Could you please provide the full code (or better simple compiled project) so that we can understand how the problem occurs?

Here is the complete code.

public static void TraversePSTWithoutMessageDelete(string pstFilePath, string attachmentDirectory)
{
    using (PersonalStorage pst = PersonalStorage.FromFile(pstFilePath))
    {
        Console.WriteLine("***********Trying to fetch Folders******************");
        FolderInfo rootFolder = pst.RootFolder;
        // Print the root folder name
        Console.WriteLine("Root Folder: " + rootFolder.DisplayName);
        // Get all subfolders recursively
        //ListSubFolders(rootFolder);

        Console.WriteLine("\n************Trying to Traverse Inbox (Hardcode)*****************");
        var inbox = pst.RootFolder.GetSubFolder("Inbox");
        Console.WriteLine($"Total Mails Found : {inbox.ContentCount}");

        if (inbox.ContentCount > 0)
        {
            MessageInfoCollection messageInfoCollection = inbox.GetContents();
            foreach (MessageInfo messageInfo in messageInfoCollection)
            {
                Console.WriteLine(" ID : " + Convert.ToBase64String(messageInfo.EntryId));
            }

            Console.WriteLine("Trying to travese all emails one by one");
            foreach (MessageInfo messageInfo in messageInfoCollection)
            {
                var id = messageInfo.EntryId;
                var entryIdBase64 = Convert.ToBase64String(id);
                // Extract the message from the PST
                MapiMessage message = pst.ExtractMessage(id);

                // Display the original subject
                Console.WriteLine("Original Subject: " + message.Subject);

                // Update the subject of the message
                string updatedSubject = "Updated Subject " + DateTime.Now;
                Console.WriteLine("Updated Subject: " + updatedSubject);

                MapiPropertyCollection keyValuePairs = new MapiPropertyCollection();

                // Update subject
                if (!message.Properties.Keys.Contains(MapiPropertyTag.PR_SUBJECT_W))
                {
                    keyValuePairs.Add(MapiPropertyTag.PR_SUBJECT_W, new MapiProperty(MapiPropertyTag.PR_SUBJECT_W, Encoding.Unicode.GetBytes(updatedSubject)));
                }

                // Update body based on content type
                if (message.BodyType == BodyContentType.Html)
                {
                    if (!message.Properties.Keys.Contains(MapiPropertyTag.PR_BODY_HTML))
                    {
                        keyValuePairs.Add(MapiPropertyTag.PR_BODY_HTML, new MapiProperty(MapiPropertyTag.PR_BODY_HTML, Encoding.Unicode.GetBytes(message.BodyHtml.Replace("amit", "Amit Singh Rawat"))));
                    }
                }
                else if (message.BodyType == BodyContentType.PlainText)
                {
                    if (!message.Properties.Keys.Contains(MapiPropertyTag.PR_BODY))
                    {
                        keyValuePairs.Add(MapiPropertyTag.PR_BODY, new MapiProperty(MapiPropertyTag.PR_BODY, Encoding.Unicode.GetBytes(message.Body.Replace("amit", "Amit Singh Rawat"))));
                    }
                }
                
                // Prepare the list of message entry IDs to change
                IList<string> changeList = new List<string> { entryIdBase64 };

                // Update messages
                inbox.ChangeMessages(changeList, keyValuePairs);
            }
        }
    }
}

Hi @asrank1008 ,
Thank you for update.

@asrank1008
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): EMAILNET-41446

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.