Getting calendar items using Exchange Web Services

I am no expert at exchange, let alone Exchange Web Services (EWS), but I recently had to use it to get at calendar information for a project. Let me tell you that the documentation for EWS sucks and the API is not very intuitive. That said, I was able to piece together what I needed. The code is not perfect and could definitely use a good once over by someone with more than 2 days experience.

The code will show how to get at calendar items, how to use a date range and how to get the body of the calendar item. I racked my brain for a while to get the body - you have  to make a call to get the calendar items and then for each item you have to go and use the ID to get its body in another call. The  idea is that the first call gets only the small parts of an item. If you want things like attachments then you make another call to get it. Here is a link to an article that gets into it.

The code is not perfect but I want to save someone the time that I spent. Please leave comments with suggestions and improvements.

UPDATE: I have attached some code. I don’t have access to an exchange server. It compiles but at least the classes are there for you. 

private List<CalendarInfo> GetCalendarEvents()
{
    List<CalendarInfo> calendarEvents = new List<CalendarInfo>();

    ExchangeServiceBinding esb =
        new ExchangeHelper().GetExchangeBinding("myUserName", "myPassword", "myDomain");

    // Form the FindItem request.
   
FindItemType findItemRequest = new FindItemType();

    CalendarViewType calendarView = new CalendarViewType();
    calendarView.StartDate = DateTime.Now.AddDays(-1);
    calendarView.EndDate = DateTime.Now.AddDays(1);
    calendarView.MaxEntriesReturned = 100;
    calendarView.MaxEntriesReturnedSpecified = true;

    findItemRequest.Item = calendarView;

    // Define which item properties are returned in the response.
   
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
    // Use the Default shape for the response.
    //itemProperties.BaseShape = DefaultShapeNamesType.IdOnly;
   
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
    findItemRequest.ItemShape = itemProperties;

    DistinguishedFolderIdType[] folderIDArray =
        new DistinguishedFolderIdType[1];
    folderIDArray[0] = new DistinguishedFolderIdType();
    folderIDArray[0].Id = DistinguishedFolderIdNameType.calendar;

    if (!string.IsNullOrEmpty(criteria.EmailAddress))
    {
        folderIDArray[0].Mailbox = new EmailAddressType();
        folderIDArray[0].Mailbox.EmailAddress = "myEmail.com";
    }
   
    findItemRequest.ParentFolderIds = folderIDArray;

    // Define the traversal type.
   
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

    try
   
{
        // Send the FindItem request and get the response.
       
FindItemResponseType findItemResponse =
            esb.FindItem(findItemRequest);

        // Access the response message.
       
ArrayOfResponseMessagesType responseMessages =
            findItemResponse.ResponseMessages;
        ResponseMessageType[] rmta = responseMessages.Items;

        int folderNumber = 0;

        foreach (ResponseMessageType rmt in rmta)
        {
            // One FindItemResponseMessageType per folder searched.
           
FindItemResponseMessageType firmt =
                rmt as FindItemResponseMessageType;

            if (firmt.RootFolder == null)
                continue ;

            FindItemParentType fipt = firmt.RootFolder;
            object obj = fipt.Item;

            // FindItem contains an array of items.
           
if (obj is ArrayOfRealItemsType)
            {
                ArrayOfRealItemsType items =
                    (obj as ArrayOfRealItemsType);
                if (items.Items == null)
                {
                    folderNumber++;
                }
                else
               
{
                    foreach (ItemType it in items.Items)
                    {

                        if (it is CalendarItemType)
                        {
                            CalendarItemType cal = (CalendarItemType)it;
                            CalendarInfo ce = new CalendarInfo();

                            ce.Location = cal.Location;
                            ce.StartTime = cal.Start;
                            ce.EndTime = cal.End;
                            ce.Subject = cal.Subject;
                            ce.Body = GetMeetingBody(esb, cal);

                            calendarEvents.Add(ce);
                        }

                    }

                    folderNumber++;
                }
            }
        }

    }
    catch (Exception e)
    {
        throw;
    }
    finally
   
{
       
    }

    return calendarEvents;
}

private string GetMeetingBody(ExchangeServiceBinding binding, CalendarItemType meeting)
{
    string meetingBody = string.Empty;
    CalendarItemType temp = null;

    // Call GetItem on each ItemId to retrieve the
    // item’s Body property and any AttachmentIds.
    //
    // Form the GetItem request.
   
GetItemType getItemRequest = new GetItemType();

    getItemRequest.ItemShape = new ItemResponseShapeType();
    // AllProperties on a GetItem request WILL return
    // the message body.
   
getItemRequest.ItemShape.BaseShape =
        DefaultShapeNamesType.AllProperties;

    getItemRequest.ItemIds = new ItemIdType[1];
    getItemRequest.ItemIds[0] = (BaseItemIdType)meeting.ItemId;

    // Here is the call to exchange.
   
GetItemResponseType getItemResponse =
        binding.GetItem(getItemRequest);

    // We only passed in one ItemId to the GetItem
    // request. Therefore, we can assume that
    // we got at most one Item back.
   
ItemInfoResponseMessageType getItemResponseMessage =
        getItemResponse.ResponseMessages.Items[0]
        as ItemInfoResponseMessageType;

    if (getItemResponseMessage != null)
    {
        if (getItemResponseMessage.ResponseClass ==
            ResponseClassType.Success
            && getItemResponseMessage.Items.Items != null
           
&& getItemResponseMessage.Items.Items.Length > 0)
        {
            temp = (CalendarItemType)getItemResponseMessage.Items.Items[0];

            if (temp.Body != null)
                meetingBody = temp.Body.Value;
        }
    }

    return meetingBody;
}

private ExchangeServiceBinding GetExchangeBinding(
      string userName, string passwotrd, string domain)
  {

      ExchangeServiceBinding binding = new ExchangeServiceBinding();

      ServicePointManager.ServerCertificateValidationCallback =
              delegate(Object obj, X509Certificate certificate, 
              X509Chain chain, SslPolicyErrors errors)
              {
                  // Replace this line with code to validate server certificate.
                  return true;
              };

      System.Net.WebProxy proxyObject = 
          new System.Net.WebProxy();
      proxyObject.Credentials = 
          System.Net.CredentialCache.DefaultCredentials;

      binding.Credentials = 
          new NetworkCredential(userName, password, domain);
 
      string server = ConfigurationManager.AppSettings["ExchangeServer"] as string;

      if (server == null || string.IsNullOrEmpty(server))
          throw new ArgumentNullException("The Exchange server Url could not be found.");

      binding.Url = server;
      Console.WriteLine("***** " + server);

      binding.Proxy = proxyObject;

      return binding;
  }

52 Comments

  • Thanks a lot for a great sample! For all the to-do that Microsoft makes about Web services being the official API for Exchange 2007, I am still having difficulty getting anything to work. Your's is the first example I've seen using a webproxy object during the binding phase. Thanks again, keep up the great posts! Code attachments for download would be a big help also.

    Glen

  • Thanks a lot ! You spared me a lot of pain, sorry, of work.

  • thanks a lot - very helpful

  • Thanks for the code, this helped me get a head start on my project of pulling calendar info from Exchange 2007. One item that I wanted to point out is that datetimes are stored as GMT in Exchange 20007. So doing queries, you will need to do some conversions between GMT and local times. Otherwise you will be displaying GMT time for your appointments or meeting and querying based on local time against GMT.

  • Do you have any idea how to access a mailbox, read its body and attachments? I would really appreciate any help in this direction.

  • &nbsp;
    &nbsp;
    &nbsp;
    Please could you provide the namespaces the following?
    &nbsp; &nbsp;CalendarItemType
    &nbsp; &nbsp;CalendarInfo
    &nbsp; &nbsp;criteria.EmailAddress
    And to complete you excellent example/article would you be able to point me in the direction of the code for the following?
    &nbsp; &nbsp;ExchangeHelper()

  • @Lewis

    Send me your email address and I'll give you what I have.

  • Can I have the namespaces for the classes/types used in the code?

  • @ Ramen

    Send me your email

  • Hello, if anyone knows what the XML that this
    code generates looks like, I'd be very
    grateful to see it. I'm trying
    to do this very thing in raw XML

    I'd love to hear from anyone.

    Jim x38444@barcore.com

  • You need the EWS library found here http://www.microsoft.com/downloads/details.aspx?FamilyID=a8c9d043-c66c-4971-9459-8d1df1608c8b&displaylang=en

    Add a refrenece to your project and this should clear things up a bit.

    i'm new to C# and would love if someone could post a working example or some working code as a console project with the existing code.

  • Can I have the namespaces for the classes/types used in the code?

  • Thanks for the code. However I require a list of participants (required,optional) for a meeting. I tried getting the same using RequiredAttendees and OptionalAttendees properties of CalendarItemType but getting null value for the same although there are required and optional attendees set for the meeting in the Exchange Server. I am using the code like below

    AttendeeType[] attendee_list = calItemType.RequiredAttendees;
    AttendeeType[] attendee_list1 = calItemType.OptionalAttendees

    but getting null values for attendee_list and attendee_list1

    What might be wrong here ?

  • Nice work.
    Thanks

    I could not get the namespace for the CalendarInfo class. which namespace it is using??

    please let me know.

    Regards
    Deewaker

  • Please tell the namespaces it is using.
    My mail id is deewaker_mca@yahoo.co.in

    Regards
    Deewaker

  • I also need namespaces the following?

    CalendarItemType

    CalendarInfo

    criteria.EmailAddress

    rmerritt@rivcoeda.org

  • If you have time to shoot me an email as well, I was interested in your CalendarInfo class and further explanation of criteria.EmailAddress. The example looks great, this is the first really useful example of using ExchangeWebServices that I've seen.

    phil.gianuzzi@jhu.edu

  • I don't know what criteria.EmailAddress does. Please explain help me. My Email is ngsinhnguyen20c2@yahoo.com. And could you guide me how to work with another objects in the Exchange, what are they namespace, library to use? Thanks a lot

  • I hate when examples use things like this:

    new ExchangeHelper().GetExchangeBinding("myUserName", "myPassword", "myDomain");

    Who's going to hardcode a password into code? The real way to do this is to use a prompt or use the default credentials for the user.

  • for credentials, use:
    esb.Credentials = CredentialCache.DefaultCredentials;

  • Hello,

    I've referenced my EWS service and downloaded the Exchange Web Services Managed API Beta (was it useful?).

    What do I need to reference now to get CalendarInfo ?

    Thanks

    My email : needhelpews@yopmail.com

  • Thanks to all of you for putting up with me not having the code. I finally found it and had to rip out the company name that I wrote it at. You should be good from there. See the attachment.

    Paul

  • pls send me an working example.

    thanks in advance


  • Do the Appointments or Tasks have unique ID's? For example in .NET I could pull a Unique ID by calling the GUID. I would like to pull the Appointment ID or Task ID and save it to a Database and use it as a reference on my other programs.

  • I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    criteria.EmailAddress


    Thx andi_1604@web.de



  • I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Thx kjhaveri@agileinfoways.com

  • The files are in the attachment above.

  • hello sir ,

    i want to do same kind of thing. so for that i have created one demo account in uctrial.com. and you know its 60 days exchange server demo account from microsoft.

    i have configured mail client in my office outlook and it synchronize with live and working well.

    so now , can i access calendar information from uctrial.com to in my Coding ( windows Apps , C#.net ) ? OR uctrial.com has banned for accessing this services.


    my email is kjhaveri@agileinfoways.com.

    Thank you.

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    jimmyd@ptg-global.com

  • I need to access someone's outlook calendar and display it in a webpart on a SharePoint page through code.

    Can you help me with the approach to do so?

  • Joseph,
    Have you figured out how to test this program? Mind to share?

    Thank you,

    -Elisabeth

  • Yes me too.. namespaces please.. great code

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    saviour@presidency.com

    thanks

  • hi
    can plz u list me the namespaces u are using.
    my EmailID is sandeep_383@yahoo.com
    Thanks

  • Hi
    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Send to : groche AT osiatis DOT com

  • All things come to those who wait.

    -----------------------------------

  • -----------------------------------------------------------
    "I have been reading your entries in the course of my afternoon escape, and i have to admit the whole post has been really enlightening and extremely nicely composed. I believed I would let you know that for some cause this blog does not exhibit nicely in Internet Explorer 8. I wish Microsoft would stop altering their software. I have a query for you personally. Do you thoughts exchanging weblog roll links? That can be seriously cool! "

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Send to : emil@withit.se

  • CalendarInfo (This is an object created by you!)

    ExchangeHelper (Object by created by adding the web service reference)

    ExchangeServiceBinding (Contained therein)

    criteria.EmailAddress (This is an object created by you!) (I deleted this clause)

  • Hello

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    criteria.EmailAddress

    Send to : yujingjean@live.cn

  • Hello I am working on a project whose goal is to provide end to read it for meetings held in rooms réunion.J would like to know how are managed the schedules of users in the Exchange server. Is what they are all the calendars of users are managed as one public calendar? I do not know how to begin the project.

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Send to :

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Send to :yunus.ates@bil.omu.edu.tr

  • I tried whith this code but not able to get the Foleders. Showing error as Error found Folder is not available.

  • Please let me what is the cause of the problem. Even it's having Public holidays list also........ Please be help on this. ASAP....... :-)

  • please also explain how to use?

    is this "private ExchangeServiceBinding GetExchangeBinding"
    wcf service if i write SL app.?

  • I am a novice in Microsoft - I come from Lotus Notes, where thsi is a very simple task. However we are looking for this solution in our new sharepoint solution.

    Could some please tell me if the above will work in 365??? and can be deployed as a solution ??? or will it be a solution on farm level ???

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    Send to :sumitdomyan@ibibo.com

  • Hi Paul, Great post!

    Simple question, how would I search for a specific Calendar, and not the default calendar as your code searches for?

    ie. My calendar name is TESTCalendar.

    Thanks.

  • Very Nice,

    This really helps since I’m currently attempting to integrate Exchange 2007 Calendar, Contacts and Messages with a custom ‘Sales Force Management’ system (in design document phase) using EWS and Developer Express Scheduling (ASPX Calendar) components. This may require data synchronization with application database tables which would be done using an independent timer thread at the web-application level.

    Thanks
    Jerome Vernon

  • Awesome article.Much thanks again.

  • Hi

    I am also in need of the references for:

    CalendarInfo

    ExchangeHelper

    ExchangeServiceBinding

    criteria.EmailAddress

    ExchangeHelper()

    Send to :annie_08@redifmail.com

  • CalendarInfo is a separated class, you can find it if you download the example code.

    Kind Regards

Comments have been disabled for this content.