question

DavidVera-3503 avatar image
0 Votes"
DavidVera-3503 asked DavidVera-3503 commented

Moving email programmatically in Exchange Online issue

I have some code that moves emails from a folder to another folder in C#.

I use EAGetMail for moving the emails. I tested this code on a basic Office365 account and it works fine, unfortunatelly I have issue with Exchange Online (plan 1).
For Office365 I can move the email, with Exchange Online the mail is not found whereas the Message-ID is retrieved.
Is this a configuration issue ?

     public MoveEmailResponse MoveEmail(EmailAccountSettings emailAccountSettings)
     {
         try
         {
             MailServer oServer = Utils.SetMailServer(emailAccountSettings);
             MailClient oClient = new MailClient("TryIt");
             oServer.SSLConnection = emailAccountSettings.Authentication.Ssl;
             oServer.Port = emailAccountSettings.Authentication.ServerPort;
             oClient.Connect(oServer);
             
             Imap4Folder storageRootFolder = Utils.FindFolder(emailAccountSettings.ExchangeRootFolder, oClient.GetFolders());
             if (storageRootFolder == null)
             {
                 throw new Exception("Folder not found!");
             }
        
             Console.WriteLine("Found !!");
             oClient.SelectFolder(storageRootFolder);
             MailInfo[] infos = oClient.GetMailInfos();
             Console.WriteLine("Nombre de mails dans le folder : " + storageRootFolder + " / "  + infos.Length);
            // step 1: create folders in inbox folder
            if (emailAccountSettings.StoragePath != null)
            {
                // split full path
                Utils.CreateExchangeStorageFolders(oClient, emailAccountSettings.StoragePath);
            }
            if (emailAccountSettings.StoragePath != null)
            {
                oClient.GetMailInfosParam.HeaderContains = emailAccountSettings.EmailId;
                infos = oClient.GetMailInfos();
                     
                if (infos.Length > 0)
                {
                    MailInfo info = oClient.GetMailInfos()[0];
                       
                    var folderPaths = emailAccountSettings.StoragePath.Split('/');
                    var count = 1;
                    // create folder path with \\
                    var results = folderPaths.Select(x => 
                        string.Join("\\", folderPaths.Take(count++))).ToList();
                    var maxIndex = results.Count - 1;
                    // taking the last element of the path 
                    oClient.Move(info, Utils.FindFolder(results[maxIndex], oClient.Imap4Folders));
                    oClient.Quit();
                    return new MoveEmailResponse("OK", "Email moved");
                }
            }
            return new MoveEmailResponse("KO", "Mail not found");
        }
        catch (Exception exception)
        {
             return new MoveEmailResponse("KO", "WebException: " + exception.Message);
         }
     }


The second implementation works fine but is less elegant. We're looping all headers of all mails whereas the previous code was using a feature of EAGetMail:


     public MoveEmailResponse MoveEmail(EmailAccountSettings emailAccountSettings)
     {
         try
         {
             MailServer oServer = Utils.SetMailServer(emailAccountSettings);
             MailClient oClient = new MailClient("TryIt");
             oServer.SSLConnection = emailAccountSettings.Authentication.Ssl;
             oServer.Port = emailAccountSettings.Authentication.ServerPort;
             oClient.Connect(oServer);
                
             Imap4Folder storageRootFolder = Utils.FindFolder(emailAccountSettings.ExchangeRootFolder, oClient.GetFolders());
             if (storageRootFolder == null)
             {
                 throw new Exception("Folder not found!");
             }
             else
             {
                 oClient.SelectFolder(storageRootFolder);
                    
                 // step 1: create folders in inbox folder
                 if (emailAccountSettings.StoragePath != null)
                 {
                     // split full path
                     Utils.CreateExchangeStorageFolders(oClient, emailAccountSettings.StoragePath);
                 }
        
                 MailInfo[] infos = oClient.GetMailInfos();
                 for (int i = 0; i < infos.Length; i++)
                 {
                     MailInfo info = infos[i];
                     Mail oMail = oClient.GetMail(info);
                    
                     foreach (var headerItem in oMail.Headers.ToList())
                     {
                         if (headerItem.HeaderValue.Contains(emailAccountSettings.EmailId) || 
                             headerItem.DecodedValue.Contains(emailAccountSettings.EmailId))
                         {
       
                             if (emailAccountSettings.StoragePath != null)
                             {
                                 var folderPaths = emailAccountSettings.StoragePath.Split('/');
                                 var count = 1;
                                 var results = folderPaths.Select(x =>
                                     string.Join("\\", folderPaths.Take(count++))).ToList();
                                 var maxIndex = results.Count - 1;
                                 oClient.Move(info, Utils.FindFolder(results[maxIndex], oClient.Imap4Folders));
                                 Console.WriteLine("Email moved");
                                 return new MoveEmailResponse("OK", "Email moved");
                             }
                             return new MoveEmailResponse("KO", "Mail not found");
                         }
                     }
                     oClient.Quit();
                 }
             }
        
             Console.WriteLine("Completed");
             return new MoveEmailResponse("KO", "Mail not found");
         }
         catch (Exception exception)
         {
             return new MoveEmailResponse("KO", "WebException: " + exception.Message);
         }
     }

Thanks

dotnet-csharpoffice-exchange-server-dev
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @DavidVera-3503,
Since the tag office-online-server-exchange focuses on technical questions about integrating Office Online Server with Exchange Server. I have removed it and added a tag related to Exchange development. Hope you get an answer soon.
Thanks for your understanding!

0 Votes 0 ·

@DavidVera-3503, I have not heard from you for a couple of days. Please let me know if there is anything that I can help in here.

0 Votes 0 ·

Hi Sorry for my delay. I was solving other issues. It seem that my issue was relative to some account parameters. Using another Exchange Plan 1 account, both codes are working. Thanks for your answer.
I tried to use this code and it works fine too. It allowed to see how Exchange Managed API work. As I'm not used to C# development, I implemented another library to reach my objective.

0 Votes 0 ·

1 Answer

JackJJun-MSFT avatar image
1 Vote"
JackJJun-MSFT answered JackJJun-MSFT edited

@DavidVera-3503, based on my test, you could try the following code to move email from one folder to another folder.

             ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
             service.Credentials= new WebCredentials("username@hotmail.com", "password");
             service.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");
             Folder rootfolder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot);
             rootfolder.Load();
             foreach (Folder folder in rootfolder.FindFolders(new FolderView(100)))
             {
                 // Finds the emails in a certain folder, in this case the Junk Email
                 FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.JunkEmail, new ItemView(10));
    
                 // This IF limits what folder the program will seek
                 if (folder.DisplayName == "Test")
                 {
                     // Trust me, the ID is a pain if you want to manually copy and paste it. This stores it in a variable
                     var fid = folder.Id;
                     Console.WriteLine(fid);
                     foreach (Item item in findResults.Items)
                     {
                         // Load the email, move the email into the id.  Note that MOVE needs a valid ID, which is why storing the ID in a variable works easily.
                         item.Load();
                         item.Move(fid);
                     }
                 }
             }

Note: I moved two emails from Junk Email Folder to Test Folder. It works for me.


If the response is helpful, please click "Accept Answer" and upvote it.


Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.