using the exchange web service API from c#
This past week I have been looking at the exchange web service API and how we can inspect Emails within Exchange. If you need to read emails from an inbox then you can very easily and quickly by using the exchange web service API which you can download from here.
I was looking for a way to check a folder for emails and then look at the xml file attachments and then do some work on the contents of the attached files – once done with the contents then mark the email as read and then move the email to an archived folder.
In the following example lets assume we will have emails which will be directed into a folder we specify using a rule, the name of the folder will be stored in the web.config file so we can make this configurable at any point, for arguments sake lets call this folder ExchangeAPIDropFolder.
The following code demonstrates how to go about this:-
[sourcecode language=”csharp”]
private static void CheckEmailFolderForContents()
{
string exchangeUsername = ConfigurationManager.AppSettings["ExchangeUsername"];
string exchangePassword = ConfigurationManager.AppSettings["ExchangePassword"];
string exchangeAutodiscoverUrl = ConfigurationManager.AppSettings["ExchangeAutodiscoverUrl"];
string exchangeAPIDropFolderFolderName = ConfigurationManager.AppSettings["ExchangeAPIDropFolderFolderName"];
string exchangeAPIDropFolderArchivedFolderName = ConfigurationManager.AppSettings["ExchangeAPIDropFolderArchivedFolderName"];
ExchangeService ews = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
{
Credentials = new WebCredentials(exchangeUsername, exchangePassword)
};
ews.AutodiscoverUrl(exchangeAutodiscoverUrl);
FindFoldersResults folderSearchResults = ews.FindFolders(WellKnownFolderName.Inbox, new FolderView(int.MaxValue));
Folder exchangeExchangeAPIArchivedFolder = folderSearchResults.Folders.ToList().Find(
f => f.DisplayName.Equals(exchangeAPIDropFolderFolderName, StringComparison.CurrentCultureIgnoreCase));
//Set the number of items we can deal with at anyone time.
ItemView itemView = new ItemView(int.MaxValue);
foreach (Folder folder in folderSearchResults.Folders)
{
if (folder.DisplayName.Equals(exchangeAPIDropFolderFolderName, StringComparison.OrdinalIgnoreCase))
{
Folder boundFolder = Folder.Bind(ews, folder.Id);
SearchFilter unreadSearchFilter =
new SearchFilter.SearchFilterCollection(
LogicalOperator.And, new SearchFilter. IsEqualTo(
EmailMessageSchema.IsRead, false));
//Find the unread messages in the email folder.
FindItemsResults<Item> unreadMessages = boundFolder.FindItems(unreadSearchFilter, itemView);
foreach (EmailMessage message in unreadMessages)
{
message.Load();
foreach (Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
fileAttachment.Load();
MemoryStream ms = new MemoryStream(fileAttachment.Content);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ms);
//TODO – Process File Contents
}
}
//Mark the message as read and then move it to the Archived Folder
message.IsRead = true;
message.Update(ConflictResolutionMode.AlwaysOverwrite);
message.Move(exchangeExchangeAPIArchivedFolder.Id);
}
}
}
}
[/sourcecode]
Thats it – enjoy and feel free to add comments or ask me about this code.
Hi Greg,
Iam a newbie to this field and i would like to know how to read emails using exchange web service API from c#, so that it will be useful for lot of beginners like me.
Hope to see a positive response from your end.
Thanks,
Ram
Hi,
this post was very helpful for me,
thank you very much,
Grzegorz
Hi Grzegorz
Glad it was of some help.
Gregor
Code worked pretty nicely although the item was not moved it stayed in the same folder because the folder id of the dropfolder and the archive folder were identical, other than that pretty good. I would change the ConflictResolutionMode to AutoResolve but upto the developer I guess.
A few questions:
1. If you don’t use a config file for the names, how else would you set it up by pointing to the source and destination folders? Would it just be:
string SourceFolder;
string DestinationFolder;
Also, I’m using the EWS API, like you have but C# is coming back at me with “The type or namespace name ‘FindFolderResults’ could not be found (are you missing a using directive or an assembly reference?”
Hi Dan
Sorry been years since I looked at this code, try checking this out here.
Hope this helps
Gregor
No Microsoft gives poor examples. For instance, this simple code (which they claim works on their site) generates an error “The name folderId does not exist in current context”:
Folder folder = Folder.Bind(service, folderId);
Folder newfolder = folder.Move(WellKnownFolderName.Drafts);
Is “folderId” a variable? I tried using the variable “Fold” down below this:
Folder folder = Folder.Bind(service, Fold);
Folder newfolder = folder.Move(WellKnownFolderName.Drafts);
That returns an unassigned variable local variable fold. I tried calling it by name:
Folder folder = Folder.Bind(service, “Fold”);
Folder newfolder = folder.Move(WellKnownFolderName.Drafts);
The error, “Id is malformed.”
Where is the code that actually works to see why everything else keeps pointing in the wrong direction?
//try this method to find folders:
public static FolderId FindFolderIdByDisplayName(ExchangeService service, string DisplayName, WellKnownFolderName SearchFolder)
{
// Specify the root folder to be searched.
Folder rootFolder = Folder.Bind(service, SearchFolder);
// Loop through the child folders of the folder being searched.
foreach (Folder folder in rootFolder.FindFolders(new FolderView(100)))
{
// If the display name of the current folder matches the specified display name, return the folder’s unique identifier.
if (folder.DisplayName == DisplayName)
{
return folder.Id;
}
}
// If no folders have a display name that matches the specified display name, return null.
return null;
}
//then use it to set the folderid like this:
FolderId folderId = FindFolderIdByDisplayName(service,”foldernameyouwanttolookfor”,WellKnownFolderName.Inbox);
//then bind to folder like this:
Folder testfolder = Folder.Bind(service, folderId );
//let me know how this goes
Worked beautifully; thanks schuster!
Many EWS examples
http://www.independentsoft.de/exchangewebservices/tutorial/index.html