• How to search appointments using EWS (Exchange Web Services)

    Posted on June 4, 2013 by in ASP.NET, C#, Dotnet

    Exchange web services enable applications to communicate with exchange server.  All the functionality that is exposed through outlook client can be done using web services. In the following example, I am going to retrieve all appointments of a user between date ranges.

    How do I access EWS?
    It is same as accessing any web service. If you are using a .NET client, you could add web reference by calling https://{server_name}/ews/exchange.asmx. This would create the proxy class for the application to use.

    (or)

    You could directly download the EWS API assembly (Microsoft.Exchange.WebServices) from the following location and add it as reference to the application.
    http://www.microsoft.com/en-us/download/details.aspx?id=28952

    Example:
    I have created a helper class that would act as a wrapper around EWS functionality. I have created a class variable ExchangeService. In the constructor, I am initializing ExchangeService object.  I am getting the service url from the appsettings and setting it to the object.  Then I am setting the credentials I use to for accessing the service.

    //Instantiate a new ExchangeService object
    exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    
    //Set the exchange WebService URL
    exchangeService.Url = new Uri(ConfigurationSettings.AppSettings["EXCHANGE_SVC_URL"]);
    
    //Set the credentials of the service to the credentials 
    //that are associated with the impersonating account.
    exchangeService.Credentials = new NetworkCredential(                                            
                               ConfigurationSettings.AppSettings["EXCHANGE_LOGIN_NAME"],
                               ConfigurationSettings.AppSettings["EXCHANGE_PASSWORD"],
                               ConfigurationSettings.AppSettings["EXCHANGE_HOST_NAME"]
                                                );
    

    I have created a public method RetrieveAppoinment which would retrieve appointments of specified user in a date range.  First thing we need to do is to inform the exchange service about the user mail box we are interested in. This we do by setting the ImpersonatorID property of the user’s email address

    //Set the ImpersonatedUserId property of the ExchangeService object to identify the impersonated user (target account). //This example uses the user's SMTP email address.
    exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailBox);
    

    Fetching appointments involves more than one step. First we need to get calendar folder of the user. The calendar folder contains all the appointments of the user.

    //bind to the calendar folder of mailBox and load all its first class properties
    CalendarFolder folder = CalendarFolder.Bind(exchangeService, WellKnownFolderName.Calendar);
    

    We need to make another call to the service to get appointments. Since we are interested in only appointments within a date range, we create a calendar view with a date range and will pass it as an argument.

    //Represents a date range view of appointments in calendar folder search operations
    //If the CalendarView element is specified the Web service returns a list of single calendar items 
    //and occurrences of recurring calendar items within the range specified by StartDate and EndDate
    CalendarView view = new CalendarView(startDate, endDate);
    
    //search for appointments matching range specified in calendar view
    FindItemsResults<Appointment> results = folder.FindAppointments(view);
    

    The appointments that were returned does not contain all the attributes. It only contains basic attributes. In order to detailed information, we need make another call to EWS. If we don’t pass the { requestedbodytype = BodyType.Text }, it will return you the calendar body in html format.

    foreach (Appointment appointment in results)
    {
       //find appointments will only give basic properties.
       //in order to get more properties (such as BODY), we need to call call EWS again
       Appointment appointmentDetailed = Appointment.Bind(exchangeService, appointment.Id, new PropertySet(BasePropertySet.FirstClassProperties) { RequestedBodyType = BodyType.Text });
    } 
    

    I have created a simple console application to test this example. I have added following settings to the app.config file.

    <appSettings>    
        <add key="EXCHANGE_SVC_URL" value="https://{service_url}"/>
        <add key="EXCHANGE_HOST_NAME" value="{domain_name}"/>
        <add key="EXCHANGE_LOGIN_NAME" value="{login_name}"/>
        <add key="EXCHANGE_PASSWORD" value="{password}"/>
      </appSettings>
    

    In the main method, I am simply calling the create appointment method with some test input.

    public static void Main(string[] args)
    {
       ExchangeHelper exchangeHelper = new ExchangeHelper();
       exchangeHelper.RetrieveAppointments("[email protected]", DateTime.Now, DateTime.Now.AddHours(2));
    }
    

    Output:
    search appointments 1

    Exchange Helper Source Code:

    using System;
    using System.Configuration;
    using System.Net;
    using Microsoft.Exchange.WebServices.Data;
    
    namespace TipsConsoleApp_2
    {
    public class ExchangeHelper
    {
        ExchangeService exchangeService;
    
        public ExchangeHelper()
        {
            //Instantiate a new ExchangeService object
            exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    
            //Set the exchange WebService URL
            exchangeService.Url = new Uri(ConfigurationSettings.AppSettings["EXCHANGE_SVC_URL"]);
    
            //Set the credentials of the service to the credentials 
            //that are associated with the impersonating account.
            exchangeService.Credentials = new NetworkCredential(                                            
                                            ConfigurationSettings.AppSettings["EXCHANGE_LOGIN_NAME"],
                                            ConfigurationSettings.AppSettings["EXCHANGE_PASSWORD"],
                                            ConfigurationSettings.AppSettings["EXCHANGE_HOST_NAME"]
                                                );            
    
        }
       
    
        public void RetrieveAppointments(string mailBox, DateTime startDate, DateTime endDate)
        {
            //Set the ImpersonatedUserId property of the ExchangeService object to identify the impersonated user (target account). 
            //This example uses the user's SMTP email address.
            exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailBox);
    
            //bind to the calendar folder of mailBox and load all its first class properties
            CalendarFolder folder = CalendarFolder.Bind(exchangeService, WellKnownFolderName.Calendar);
    
            //Represents a date range view of appointments in calendar folder search operations
            //If the CalendarView element is specified the Web service returns a list of single calendar items 
            //and occurrences of recurring calendar items within the range specified by StartDate and EndDate
            CalendarView view = new CalendarView(startDate, endDate);
    
            //search for appointments matching range specified in calendar view
            FindItemsResults<Appointment> results = folder.FindAppointments(view);
            
            //print results
            foreach (Appointment appointment in results)
            {
                //find appointments will only give basic properties.
                //in order to get more properties (such as BODY), we need to call call EWS again
                Appointment appointmentDetailed = Appointment.Bind(exchangeService, appointment.Id, new PropertySet(BasePropertySet.FirstClassProperties) { RequestedBodyType = BodyType.Text });
                Console.WriteLine("Appointment ID:  " + appointment.Id);
                Console.WriteLine("Subject:         " + appointment.Subject);
                Console.WriteLine("Start Time:      " + appointment.Start.ToString("M/d/yyyy h:mm tt") + appointment.TimeZone);
                Console.WriteLine("End Time:        " + appointment.End.ToString("M/d/yyyy h:mm tt") + appointment.TimeZone);
                if(!string.IsNullOrEmpty(appointmentDetailed.Body.Text))
                    Console.WriteLine("Body             " + appointmentDetailed.Body.Text.Trim());
                Console.WriteLine("Required Attendees");
                foreach (Attendee attendee in appointmentDetailed.RequiredAttendees)
                {
                    Console.WriteLine("             " + attendee.Address);
                }
                Console.WriteLine("Optional Attendees");
                foreach (Attendee attendee in appointmentDetailed.OptionalAttendees)
                {
                    Console.WriteLine("             " + attendee.Address);
                }
                Console.WriteLine();
            }
    
            //Set it back to null so that any actions that will be taken using the exchange service
            //applies to impersonating account (i.e.account used in network credentials)
            exchangeService.ImpersonatedUserId = null;
        }
    }
    }
    
    Be Sociable, Share!

    Written by

    Software architect with over 10 years of proven experience in designing & developing n-tier and web based software applications, for Finance, Telecommunication, Manufacturing, Internet and other Commercial industries. He believes that success depends on one's ability to integrate multiple technologies to solve a simple as well as complicated problem.

    View all articles by

    Email : [email protected]

    2 Responsesso far.

    1. […] If you are new to using EWS, I would recommend you to read below articles. How to create appointment using EWS How to search appointments using EWS […]

    2. SharkBaitNZ says:

      Can this be done in VB.NET as well?

    Leave a Reply