What is the EWS Managed API and Exchange Server Binding?

Overview / Survival Guide

What is the Microsoft Exchange Server Managed API?

The EWS Managed API provides a managed interface for developing client applications that use Exchange Web Services (EWS). The EWS Managed API communicates with the Exchange Client Access server by means of EWS SOAP messages.

At the time of this article, the EWS Managed API 1.2 introduces the following important changes that might affect your client applications:

Microsoft Exchange Server 2010 Service Pack 2 (SP2) is now the targeted version

The following new functionality is exposed:
Getting password expiration date
Updates to the contact type
Store entry identifiers returned on items
Asynchronous notifications
DateTime object precision values

Documentation
Download

Since i am using the Exchange Web Services Managed API approach, you will need to download it here and add the "Microsoft.Exchange.WebServices.dll" to your project. If you have your domain hosted in your corporation, elsewhere or a hybrid solution  you will PROBABLY need a CNAME in your Server in order to resolve the AUTODISCOVERY for Exchange On-Line in order to use Binding.

This CNAME will create a bridge from your server to Exchange On-Line, something like this:

Type: MX
Host: yourhost.com
MX Server: 99999999.mail.outlook.com
TTL: 3.600 or 1 hour
Priority: 0

Ask your System Administrator for this
 

What is the Service Binding?   

The Microsoft Exchange Web Services Managed API have 2 main classes, the FOLDER Class and the ITEM Class. All these 2 need a ServiceObject in order to communicate with a Exchange Web service.

Service Binding use the Autodiscover Object in order to get a Exchange Web Service endpoint URL, something like this** https://SERVER.outlook.com/EWS/Exchange.asmx**.

At theTOP of the hierarchy there is a **SERVICEOBJECT **that is a type of ExchangeService() Object

So what next? let’s see in more detail, what Outlook do if you add a Microsoft Exchange Account?

http://exchws.files.wordpress.com/2011/12/image_thumb2.png?w=457&h=318

In this case Outlook will try to resolve thru Autodiscover the domain in the E-mail Address field, and get the Endpoint for the Exchange Web Service, if the credentials are OK, all user configurations and Mail will be attached to Outlook

Service Binding do the same thing, the only difference is that you will assign properties values to a ExchangeService(), and assign user information’s like the Endpoint URL in order to you can use All Objects in the FOLDER and ITEM Class

Another approach is to activate this Property in your Binding Method, so you can prevent the Autodiscover from looking in the Local Active Directory

// Prevent the AutodiscoverService from 
//looking in the local Active Directory 
// for the Exchange Web Services Services SCP. 
ads.EnableScpLookup = false;

If you are in a network with a Proxy like ISA, you have to pass a WebRequest Proxy otherwise you will get the bellow error:

407 Proxy Authentication Required ( Forefront TMG requires authorization to fulfill the request. Access to the Web Proxy filter is denied. )

Pass a Proxy Object in your Code

// set up the proxy 
WebProxy proxy = new  WebProxy("valid-proxy", 8080); 
proxy.Credentials = new
    NetworkCredential("valid-user","valid-password","valid-domain"); 
service.WebProxy = proxy;

  Creating a Binding Object to Live@Edu and Office 365  

using Microsoft.Exchange.WebServices.Autodiscover; 
using Microsoft.Exchange.WebServices.Data;
public static  ExchangeService GetBinding() 
{ 
    try
    { 
        //Create Service 
        ExchangeService service = new
            ExchangeService(ExchangeVersion.Exchange2010_SP1); 
        //Assign Credentials 
        service.Credentials = new
            WebCredentials("admin@contoso.com", "password");  
        // Create an instance of the AutodiscoverService. 
        AutodiscoverService ads = new
            Autodiscover.AutodiscoverService(); 
        // Enable tracing. 
        ads.TraceEnabled = true; 
        // Set the credentials. 
        ads.Credentials = service.Credentials; 
        // Prevent the AutodiscoverService from 
        //looking in the local Active Directory 
        // for the Exchange Web Services Services SCP. 
        ads.EnableScpLookup = false; 
        // Specify a redirection URL validation 
        //callback that returns true for valid URLs. 
        ads.RedirectionUrlValidationCallback = 
            RedirectionUrlValidationCallback; 
        // Get the Exchange Web Services URL for the user’s mailbox. 
        GetUserSettingsResponse response = 
            ads.GetUserSettings("admin@contoso.com", 
                UserSettingName.ExternalEwsUrl); 
        // Extract the Exchange Web Services URL from the response. 
        var externalEwsUrl = new
        Uri(response.Settings[UserSettingName.ExternalEwsUrl].ToString()); 
        // Set the URL of the ExchangeService object. 
        service.Url = externalEwsUrl; 
        return service; 
    } 
    catch (AutodiscoverRemoteException ex) 
    { 
        Console.WriteLine("Exception thrown: " + ex.Error.Message); 
        return null; 
    } 
}
 
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; 
}

For some reason i couldn't make this work in SharePoint 2010, so i had to find a fix for that, so if you are using AutoDiscovery in Office 365 or Live@Edu maybe you will have to run the above method in a Console Application, catch the EndPoint URL and use like this:

/// <summary> 
/// Gets the binding. 
/// </summary> 
/// <returns></returns> 
public static  ExchangeService GetBinding() 
{ 
    try
    { 
        //Create Service 
        ExchangeService service = new
            ExchangeService(ExchangeVersion.Exchange2010_SP1); 
        //Assign Credentials 
        service.Credentials = new
            WebCredentials("admin@contoso.com", "password");  
        ServicePointManager.ServerCertificateValidationCallback += 
            RemoteCertificateValidationHandler; 
        //Change this line by your EndPoint Url 
        service.Url = new  Uri("https://amsprdXXXX.outlook.com/EWS/Exchange.asmx"); 
        return service; 
    } 
    catch (AutodiscoverRemoteException ex) 
    { 
        Console.WriteLine("Exception thrown: " + ex.Error.Message); 
        return null; 
    } 
}
private static  bool RemoteCertificateValidationHandler  
    (object sender, X509Certificate certificate, 
    X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    return true; //ignore the checks and go ahead 
}

References

Joao Livio - Online Services Blog
http://exchws.wordpress.com/

Microsoft Exchange Web Services API 1.2
http://msdn.microsoft.com/en-us/library/dd633709(v=exchg.80).aspx