Creating an Exchange Web Services Client Application

Topic Last Modified: 2009-07-15

You can use Microsoft Visual Studio 2005 or Visual Studio 2008 to create a simple Exchange Web Services client application. This walkthrough describes how to create a draft e-mail message, how to set up different parts of the application, and how to handle the response. Use this walkthrough to become familiar with the object model that is created by using the Visual Studio 2005 or Visual Studio 2008 proxy generator.

Prerequisites

  • Microsoft Exchange Server 2007
  • Visual Studio 2005 or Visual Studio 2008

Procedure

Creating an Exchange Web Services client application involves the following steps:

  • Setting up the Visual Studio 2005 or Visual Studio 2008 project on the client application.
  • Validating the server certificate.
  • Creating the service binding.
  • Creating the CreateItem request.
  • Sending the request and getting the response.
  • Checking the status of each response.
  • Checking and casting the response type and accessing the high-level objects.

To set up the client application project

  1. Create a new console application project.

  2. Add proxy classes to the project. For more information, see Creating a Proxy Reference by Using Visual Studio 2005 or Visual Studio 2008.

To add X509 certificate validation code

  • Add code to Main() to validate the server certificate. For more information, see Validating X509 Certificates for SSL over HTTP.

    static void Main(string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback =
        delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            // Replace this line with code to validate server certificate.
        };
    

Note

The Autodiscover sample includes an example that shows how to implement the certificate validation. For more information, see Navigating the Autodiscover Sample Application Source Code.

To create the service binding

  1. Add the ExchangeServiceBinding object to Main(). For more information, see Setting Up the ExchangeServiceBinding Proxy Class.

  2. Specify the version of schema files that should be used to validate and process client requests. For more information about setting the request version, see Versioning Requests (Exchange Web Services).

  3. Set the credentials for the application. You can explicitly set the user credentials, as shown in the preceding code example, or use the default credentials that are supplied by types in the System.Net.CredentialCache namespace.

  4. Set the service URL.

    // Identify the service binding and the user.
    ExchangeServiceBinding service = new ExchangeServiceBinding();
    service.Credentials = new NetworkCredential("<username>", "<password>", "<domain>");
    service.RequestServerVersionValue = new RequestServerVersion();
    service.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
    service.Url = @"https://<FQDN>/EWS/Exchange.asmx";
    

Important

Exchange Web Services clients should call the Autodiscover service to get the URL of the Client Access server that is used for a particular mailbox account.

To create the CreateItem request

  1. Create the CreateItemType container that will hold the information that describes the e-mail message to be created in the Exchange store. The T:ExchangeWebServices.CreateItemType represents the SOAP message that will be sent to create the item.

    CreateItemType createEmailRequest = new CreateItemType();
    
  2. Specify how the e-mail message will be handled. Notice that the MessageDispositionSpecified property is set to true. For more information, see Using the *Specified Properties. Note that the MessageDisposition property is only used for the creation of MessageType objects.

    createEmailRequest.MessageDisposition = MessageDispositionType.SaveOnly;
    createEmailRequest.MessageDispositionSpecified = true;
    
  3. Specify where the saved item is stored. In this case, the item is saved in the Sent Items folder.

    createEmailRequest.SavedItemFolderId = new TargetFolderIdType();
    DistinguishedFolderIdType sentitems = new DistinguishedFolderIdType();
    sentitems.Id = DistinguishedFolderIdNameType.sentitems;
    createEmailRequest.SavedItemFolderId.Item = sentitems;
    
  4. Create the array of items. You can create many items in a single request.

    createEmailRequest.Items = new NonEmptyArrayOfAllItemsType();
    
  5. Create an e-mail message and set the properties that describe the message.

    MessageType message = new MessageType();
    message.Subject = "Daily Report";
    message.Body = new BodyType();
    message.Body.BodyType1 = BodyTypeType.Text;
    message.Body.Value = "(1) Handled customer issues, (2) Saved the world.";
    message.Sender = new SingleRecipientType();
    message.Sender.Item = new EmailAddressType();
    message.Sender.Item.EmailAddress = "user1@example.com";
    message.ToRecipients = new EmailAddressType[1];
    message.ToRecipients[0] = new EmailAddressType();
    message.ToRecipients[0].EmailAddress = "user2@example.com";
    message.Sensitivity = SensitivityChoicesType.Normal;
    
  6. Add the e-mail message to the array of items to create. The CreateItemType object contains an Items property that returns a NonEmptyArrayOfAllItemsType object. The NonEmptyArrayOfAllItemsType object contains an Items property because the NonEmptyArrayOfAllItemsType type contains an XML schema choice element that describes the potential for having one or more items that share a common base type of type ItemType. For more information, see XML Schema Choice Element Proxy Artifacts.

    createEmailRequest.Items.Items = new ItemType[1];
    createEmailRequest.Items.Items[0] = message;
    

To send the request and get the response

  • Send the request and get the response.

    CreateItemResponseType createItemResponse = esb.CreateItem(createEmailRequest);
    ArrayOfResponseMessagesType responses = createItemResponse.ResponseMessages;
    ResponseMessageType[] responseMessages = responses.Items;
    

To check the status of each response

  • Check to determine whether the response contains an error or warning.

    foreach (ResponseMessageType respMsg in responseMessages)
    {
        if (respMsg.ResponseClass == ResponseClassType.Error)
        {
            throw new Exception("Error: " + respMsg.MessageText);
        }
        else if (respMsg.ResponseClass == ResponseClassType.Warning)
        {
            throw new Exception("Warning: " + respMsg.MessageText);
        }
    

To check and cast the response type and access the high-level objects

  1. Check the type of response that is returned in the request. For more information about responses, see Exchange Web Services Responses.

    if (responseMessage is ItemInfoResponseMessageType)
    {
        ItemInfoResponseMessageType createItemResp = (responseMessage as ItemInfoResponseMessageType);
        ArrayOfRealItemsType aorit = createItemResp.Items;
    
  2. Cast the objects in the response to the correct types. In this case, you must cast the ItemType to a MessageType because that is the type for e-mail messages. For more information about casts, see XML Schema Choice Element Proxy Artifacts.

        foreach (ItemType item in aorit.Items)
        {
            if (item is MessageType)
            {
                MessageType myMessage = (item as MessageType);
                Console.WriteLine("Created item: " + myMessage.ItemId.Id);
            }
            // TODO: Add logic to check and cast for all other types.
        }
    }
    

Important

The ArrayOfRealItemsType object is null in the response if the MessageDisposition property of the CreateItemType is set to SendAndSaveCopy or SendOnly. Essentially, any disposition that causes the e-mail to be sent will return an ArrayOfRealItemsType object set to null.

Remarks

The ExchangeWebServices namespace is created when the Web service proxy assembly is created. This namespace is not included in any assembly that ships with Exchange Server 2007. The name of the namespace that is generated by the proxy generator is arbitrary. The name ExchangeWebServices is used in this example for readability and conformity.

Example

Description

The following code example shows a Web service client that creates an e-mail item in the Sent Items default folder.

Code

using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

// The ExchangeWebServices namespace was created by using Visual Studio // 2005 and the Add Web Reference wizard.
using ExchangeWebServices;

namespace E12_685_018
{
    partial class Program
    {
        static void Main(string[] args)
        {
            ServicePointManager.ServerCertificateValidationCallback =
            delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                // Replace this line with code to validate the server certificate.
            };

            // Identify the service binding and the user.
            ExchangeServiceBinding esb = new ExchangeServiceBinding();
            esb.Credentials = new NetworkCredential("<username>", "<password>", "<domain>");
            esb.Url = @"https://<FQDN>/EWS/Exchange.asmx";

            // Specify the request version.
             esb.RequestServerVersionValue = new RequestServerVersion();
             esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

            // Create the CreateItem request.
            CreateItemType createEmailRequest = new CreateItemType();

            // Specifiy how the e-mail will be handled.
            createEmailRequest.MessageDisposition = MessageDispositionType.SaveOnly;
            createEmailRequest.MessageDispositionSpecified = true;

            // Specify the location of sent items. 
            createEmailRequest.SavedItemFolderId = new TargetFolderIdType();
            DistinguishedFolderIdType sentitems = new DistinguishedFolderIdType();
            sentitems.Id = DistinguishedFolderIdNameType.sentitems;
            createEmailRequest.SavedItemFolderId.Item = sentitems;

            // Create the array of items.
            createEmailRequest.Items = new NonEmptyArrayOfAllItemsType();

            // Create a single e-mail message.
            MessageType message = new MessageType();
            message.Subject = "Daily Report";
            message.Body = new BodyType();
            message.Body.BodyType1 = BodyTypeType.Text;
            message.Body.Value = "(1) Handled customer issues, (2) Saved the world.";
            message.Sender = new SingleRecipientType();
            message.Sender.Item = new EmailAddressType();
            message.Sender.Item.EmailAddress = "user1@example.com";
            message.ToRecipients = new EmailAddressType[1];
            message.ToRecipients[0] = new EmailAddressType();
            message.ToRecipients[0].EmailAddress = "user2@example.com";
            message.Sensitivity = SensitivityChoicesType.Normal;

            // Add the message to the array of items to be created.
            createEmailRequest.Items.Items = new ItemType[1];
            createEmailRequest.Items.Items[0] = message;

            try
            {
                // Send a CreateItem request and get the CreateItem 
// response.
                CreateItemResponseType createItemResponse = esb.CreateItem(createEmailRequest);
                ArrayOfResponseMessagesType responses = createItemResponse.ResponseMessages;
                ResponseMessageType[] responseMessages = responses.Items;

                // Access the response messages.
                foreach (ResponseMessageType respMsg in responseMessages)
                {
                    if (respMsg.ResponseClass == ResponseClassType.Error)
                    {
                        throw new Exception("Error: " + respMsg.MessageText);
                    }
                    else if (respMsg.ResponseClass == ResponseClassType.Warning)
                    {
                        throw new Exception("Warning: " + respMsg.MessageText);
                    }

                    // Check to determine whether the response message is the correct type.
                    if (respMsg is ItemInfoResponseMessageType)
                    {
                        ItemInfoResponseMessageType createItemResp = (respMsg as ItemInfoResponseMessageType);
                        ArrayOfRealItemsType aorit = createItemResp.Items;

                        foreach (ItemType item in aorit.Items)
                        {
                            if (item is MessageType)
                            {
                                MessageType myMessage = (item as MessageType);
                                Console.WriteLine("Created item: " + myMessage.ItemId.Id);
                                Console.ReadLine();
                            }
                            // TODO: Add logic to check and cast for all other types.
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}