Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)

exlogoIf you haven’t already had the need, I’m sure you will at some point, to either retrieve email or send email through Exchange (not just relay or connect to Outlook) using .net. Since Microsoft introduced the Microsoft Exchange Web Services Managed API 2.0 this task has become much more efficient No more clunky 2.0 type web service references etc. Below is a complete chuck of code with a few samples. One sample function sends an email, the other retrieves email messages from an inbox with the option of filters.

The short steps are:

1. Download the api here
2. Add a reference (not a web reference) to the dll (usually C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll)
3. Add the below code into a new class
4. Fill in your details (username, pass, domain)
5. Fill in your service URL (http://yourmailserver.domain.com/EWS/Exchange.asmx) – If you don’t know this already, you can uncomment the “AutodiscoverUrl” line and break on it to find what your URL is. I don’t suggest using AutodiscoverUrl unless you need to, it performs very poor and will slow down your application. But if you’re okay with the speed, you can remove the .url line and just keep the .autodiscoverurl line.

Update: Additional info for message body data here.

The Code (intended for example – not polished):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Exchange.WebServices.Data;

namespace testExEmail
{
    class ExConnect
    {

        public string sentEmailTest()
        {
            string statusMsg = "email sent!";

            ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
            service.Credentials = new WebCredentials("username", "password", "yourdomain");

            // service.AutodiscoverUrl("username@yourdomain.com", RedirectionUrlValidationCallback);
            service.Url = new System.Uri("https://exserver.yourdomain.com/EWS/Exchange.asmx");

            EmailMessage email = new EmailMessage(service);
            email.ToRecipients.Add("username@yourdomain.com");
            email.Subject = "Test Message";
            email.Body = new MessageBody("Sample message sent via EWS Managed API");
            email.Send();

            return statusMsg;

        }

        public string getEmailTest()
        {
            string statusMsg = "emails grabbed!";

            ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
            service.Credentials = new WebCredentials("username", "password", "yourdomain");
            // service.AutodiscoverUrl("username@yourdomain.com", RedirectionUrlValidationCallback);
            service.Url = new System.Uri("https://exserver.yourdomain.com/EWS/Exchange.asmx");

            //filter
            // Add a search filter that searches on the body or subject.
            List<SearchFilter> searchFilterCollection = new List<SearchFilter>();
            searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "A Subject"));
            //searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Body, "Some Body"));

            // Create the search filter.
            SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.Or, searchFilterCollection.ToArray());

            var inbox = new FolderId(WellKnownFolderName.Inbox);
            var iv = new ItemView(10);

            var items = service.FindItems(inbox, searchFilter, iv);

            statusMsg = items.TotalCount.ToString();

            foreach (EmailMessage msg in items.Take(10))
            {

                statusMsg = statusMsg + msg.Subject + " -- ";

            }

            return statusMsg;

        }

        private static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            // The default for the validation callback is to reject the URL.
            bool result = false;

            Uri redirectionUri = new Uri(redirectionUrl);

            // Validate the contents of the redirection URL. In this simple validation
            // callback, the redirection URL is considered valid if it is using HTTPS
            // to encrypt the authentication credentials. 
            if (redirectionUri.Scheme == "https")
            {
                result = true;
            }
            return result;
        }

        private static bool CertificateValidationCallBack(
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }

            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            {
                if (chain != null && chain.ChainStatus != null)
                {
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    {
                        if ((certificate.Subject == certificate.Issuer) &&
                           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        {
                            // Self-signed certificates with an untrusted root are valid. 
                            continue;
                        }
                        else
                        {
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            {
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                return false;
                            }
                        }
                    }
                }

                // When processing reaches this line, the only errors in the certificate chain are 
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange server installations, so return true.
                return true;
            }
            else
            {
                // In all other cases, return false.
                return false;
            }
        }

    }
}

Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)

7 thoughts on “Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)

Leave a comment