8

Added: thanks to user @grapkulec, I am using

using Microsoft.Exchange.WebServices.Data;

I am trying to move an email to a folder that I've already created in Outlook (using MS Exchange). So far, I've been able to move the email to the drafts or another well known folder name, but have had no success moving it to a folder I created called "Example."

foreach (Item email in findResults.Items)
email.Move(WellKnownFolderName.Drafts);

The above code works; but I don't want to use the well known folders. And, if I try to change the code to something like:

email.Move(Folder.(Example));

or

email.Move(Folder.["Example"]);

It doesn't move (in both cases, throws an error). I've found tons of examples of how to move emails into folders on MSDN, SO and general C# - but ONLY of folders that are "well known" to Outlook (Drafts, Junk Email, etc), which doesn't work with a folder that I've created.

Kprof
  • 742
  • 1
  • 8
  • 16

3 Answers3

11

Solved!

The Move command failed regardless of several attempts because the ID was malformed. Apparently a move operation doesn't allow use of names. I had tried DisplayName as an identifier and that's what kept throwing me off. Finally, I gave up on DisplayName, which would have helped. Instead I pointed to the ID (which stopped the annoying "ID is malformed" error) by storing it in a variable, and the move worked.

Code:

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 == "Example")
    {
        // 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);
        }
    }
}
CarenRose
  • 1,266
  • 1
  • 12
  • 24
Kprof
  • 742
  • 1
  • 8
  • 16
  • 1
    You really should use filters for getting your "Example" folder if that code is going live. And even without filters you should move FindItems outside of loop because what's the point of getting exactly same items up to 100 times? And there is also MoveItems method in ExchangeService class which makes possible to move multiple items in one call. So basically your code could take 3-4 lines of code (not counting safety ifs and such of course) – grapkulec Dec 05 '12 at 10:44
  • 1
    Thanks; this code works and can be tweaked to where appropriate adjustments can be made. – Kprof Dec 05 '12 at 16:01
8

It seems you are using EWS Managed API so here is my answer how I do such things.

Move method on items can accept WellKnownFolderName or folder id. If I understand it correctly you want to move you email into folder named "Example". So first you need to get folder object for this folder:

var filter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Example");
var view = new FolderView(1)
{
    PropertySet = new PropertySet(BasePropertySet.FirstClassProperties)
};
var findFoldersResults = exService.FindFolders(filter, view);
folder = findFoldersResults.FirstOrDefault(f => f.DisplayName.Equals("Example", StringComparison.OrdinalIgnoreCase));

Now you should have your "Example" folder variable and you can pass its id to Move method of an email. For more details check msdn pages about how to work with EWS Managed API, quite a lot of simple and basic usage examples there.

BTW: WellKnownFolderNames enum is a convenience type for most common Exchange folders like Inbox, Sent Items, etc. Anything else you have to retrieve on your own by searching an/or binding just in case of any other Exchange objects.

grapkulec
  • 1,022
  • 13
  • 28
  • I'm working on trying this; however, I've accessed the MSDN pages and I would caution other users away from it for this problem. They are incredibly unhelpful; they only use examples with well known folder names - which, the same syntax does not work whatsoever with created folders. So far, for instance, using their bind method, yields no success with moving. Nor does the find method yield any success. Unless, of course, you want to move it to a well known folder! – Kprof Dec 03 '12 at 15:45
  • Unfortunately, this generates several overload errors, so it's incompatible with the current code. – Kprof Dec 03 '12 at 16:06
  • well, this is exactly code I use in a product working at heavy load and in quite different environments so I know it works. But I won't lie that I wrote it perfectly first time, it took me a lot of google browsing and trial an error before I understood how all pieces come together. Maybe you should update your question with your current code snippet so we could see some context. Your question about moving to folders was already answered. Sorry if you struggling to make my example work but don't see how I can be more of help without knowing more details. – grapkulec Dec 04 '12 at 14:28
  • @Peroxy what exactly is not working? "it doesn't work" is sth I would expect to hear from customer not from fellow dev :) – grapkulec Apr 10 '17 at 15:24
  • 1
    As stated above by OP: Unfortunately, this generates several overload errors, so it's incompatible with the current code. – Peroxy Apr 10 '17 at 15:41
  • strange because I didn't touch my code that moves items to folders since years and we also are using EWS 2.2 which is latest released as far as I know so... yeah, strange – grapkulec Apr 10 '17 at 16:20
  • Note several years later: in version 2.2.0 of Microsoft.Exchange.WebServices, there are only 4 overloads of `FindFolders()`, and all take either a `FolderId` or a `WellKnownFolderName` as the first parameter. – CarenRose Nov 08 '19 at 20:56
3

Based on these answers, created a working method for moving to folders, might be useful to someone:

/// <summary>
/// Moves the email to the specified folder.
/// </summary>
/// <param name="mail">Email message to move.</param>
/// <param name="folderName">Display name of the folder.</param>
public void MoveToFolder(EmailMessage mail, string folderName)
{
    Folder rootfolder = Folder.Bind(_exchangeService, WellKnownFolderName.MsgFolderRoot);
    rootfolder.Load();
    Folder foundFolder = rootfolder.FindFolders(new FolderView(100)).FirstOrDefault(x => x.DisplayName == folderName);
    if (foundFolder == default(Folder))
    {
        throw new DirectoryNotFoundException(string.Format("Could not find folder {0}.", folderName));
    }

    mail.Move(foundFolder.Id);
}
Peroxy
  • 646
  • 8
  • 18