Share via


Exchange Web Service learnings

Just the other day I worked on a requirement to get emails from exchange.

This sounds simple right?

Back in the day I would use IMAP to do this, but starting in 2016 that is disabled by default, review; /en-us/Exchange/plan-and-deploy/deployment-ref/network-ports.

Where I work there is a development environment, fun side story is I was told it was running Exchange 2016, turns out not to be true.

Exchange comes with a web service, you can add a reference to that web service to your project, but it can be difficult to work with.

An API was built, mostly this API abstracts the different versions of Exchange web services, as there are small differences. This allow your program to not have to be changed (service reference) for each version of exchange.

You can download the source code here: https://github.com/OfficeDev/ews-managed-api

NOTE: the nugget package is 3 years old!! So it doesn't contain any of the recent fixes or add-ins, including enum support of Exchange 2016, best to download the code and reference the compiled assembly.

Lets review getting the object:

string username, password, emailaddress, domainname

emailaddress = "myname@mydomain.com"

username = "myUserName"

domainname = "MyDomain"

password  = "1234567"

NOTE: you do not need to have the user information above, the code will use the signed account that the code runs under.

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);

//Depending on how AD is setup one of the two options will work.

//service.Credentials = new WebCredentials(emailaddress,password);

For my tests, this version worked:

service.Credentials = new WebCredentials(emailaddress,password,domainname);

//Now it's time to auto discover the URL, note if you have the URL you can cut some mill-seconds from the processing.

//Auto discover the URL via email

service.AutodiscoverUrl(emailaddress); //this attempts to find the web service by using the email address to search the domain of the user.

//OR

service.Url = new Uri("https://urltoexchange/ews/exchange.asmx");

If no errors or exceptions you can now go onto the next phase, getting the items, note, there are three ways shown:

//1: Use a filter to search for items that contain a string

var items = service.FindItems(
//Find Mails from Inbox of the given Mailbox
new FolderId(WellKnownFolderName.Inbox, new Mailbox(emailaddress)),
//Filter criterion
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {
new SearchFilter.ContainsSubstring(ItemSchema.Subject, "string to search for"),
new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false)
}),
//View Size as 15
new ItemView(15));

NOTE: the above will show only 15 items, as well as only show unread emails.

//2: Just show items that have been unread.

var items = service.FindItems(
//Find Mails from Inbox of the given Mailbox
new FolderId(WellKnownFolderName.Inbox, new Mailbox(emailaddress)),
//Filter criterion
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {
new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false)
}),
//View Size as 15
new ItemView(15));

Note: just like the previous this only shows unread emails and only 15.

//3: Show all emails (up to view size)

var items = service.FindItems(new FolderId(WellKnownFolderName.Inbox, new Mailbox(emailaddress)),new ItemView(15));

This simply gets all the emails up to 15 limit.

Now to process the emails, the above simply got ID's.

foreach (EmailMessage msg in items)
{
//Retrieve Additional data for Email
EmailMessage message = EmailMessage.Bind(service,
(EmailMessage.Bind(service, msg.Id)).Id,
new PropertySet(BasePropertySet.FirstClassProperties,
new ExtendedPropertyDefinition(0x1013, MapiPropertyType.Binary)));
Console.Write(message.Subject);}

This gets the message for each of the Id's retrieved. The message object includes many properties such as body and to/from as well as subject.

The above helps for you to understand the basics, there are many more examples of using this API via: https://code.msdn.microsoft.com/exchange/Exchange-2013-101-Code-3c38582c