Migrating to Exchange Web Services, Part 1: Messaging

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Topic Last Modified: 2008-06-25

By Bob Bunn, Programming Writer

Applications that work with Microsoft Office Outlook and Microsoft Exchange Server typically extend one or more of the following features:

  • Messaging
  • Calendaring (including meetings and appointments)
  • Search
  • Contact management

This is the first in a five-part series of articles that shows you how you can use Exchange Web Services to replace the legacy Exchange Server APIs for custom applications that extend these features. Each article will focus on one feature area, and the final article in the series will provide a fully functioning set of EWS-based applications that showcase these features.

Before you read further, you might want to review some background information about Exchange Web Services in Microsoft Exchange Server 2007. For information about the benefits of using Exchange Web Services, see Exchange Web Services Developer Overview. For information about how the legacy APIs map to EWS, see Migrating from Exchange 2007 Legacy APIs.

In this article, I will compare the use of legacy APIs against EWS for messaging tasks.

Messaging Overview

The most common task for a messaging application is to send e-mail messages. Sending an e-mail message basically involves the following steps:

  1. Creating a Message object.
  2. Addressing the message (including from and to).
  3. Providing the subject line.
  4. Including the body of the message.
  5. Connecting to the computer that is running Exchange Server.
  6. Sending the message.

The examples in this article show how the legacy APIs and Exchange Web Services handle the sending of an e-mail message.

Using CDOEX to Send a Message

Collaboration Data Objects for Exchange 2000 Server (CDOEX) is commonly used by applications to send e-mail messages. The following code example uses the CDO Message object to create and send a message.

With New CDO.Message
' Indicate who is sending the message.
.From = "yourname@domain.com"

' Address the message.
.To = "denise@domain.com, aidan@domain.com"

' Set the subject matter.
.Subject = "Siberian Tigers"

' Fill in the body text. 
' Use plain text formatting.
.TextBody = _
"Did you know there are estimated to be only " & _
"about 400 of these magnificent creatures left in the wild?"

' Send the message.
.Send()
End With

The CDOEX code is short, straightforward, and simple, but note that not every property is strongly typed. For example, the From and To properties are string representations of compound properties. To indicate a friendly name like Denise Smith, instead of denise@domain.com, you have to find the name in the Exchange directory. Exchange Web Services uses compound objects. This makes all the properties of the object available to the application.

Using WebDAV to Send a Message

The following code example uses the WebDAV PUT and MOVE verbs to create and send an e-mail message. Notice the absence of any object representation of a message. The application performs the transaction by building string commands.

Dim strSubURI As String
Dim strTempURI As String
Dim strAlias As String
Dim strUserName As String
Dim strPassWord As String
Dim strExchSvrName As String
Dim strTo As String
Dim strSubject As String
Dim strBody As String
Dim strText As String
Dim bRequestSuccessful As Boolean
Dim xmlReq As IXMLHTTPRequest
Dim xmlReq2 As IXMLHTTPRequest

' Exchange server name
strExchSvrName = "ContosoExchange01"

' Alias of the sender
strAlias = "chris@contoso.com"

' User name of the sender
strUserName = "ContosoUsers01\chris"

' Password of the sender
strPassWord = "!Password"

' E-mail address of the recipient
strTo = "carter@contoso.com"

' Subject of the message
strSubject = "Siberian Tigers"

' Text body of the message
strBody = "There are estimated to be 400 in the wild"
' Build the submission URI. If Secure Sockets Layer (SSL)
' is set up on the server, use "https://" instead of "http://".
strSubURI = "http://" & strExchSvrName & "/exchange/" & _
strAlias & "/%23%23DavMailSubmissionURI%23%23/"

' Build the temporary URI. If SSL is set up on the
' server, use "https://" instead of "http://".
strTempURI = "http://" & strExchSvrName & "/exchange/" & _
strAlias & "/drafts/" & strSubject & ".eml"

' Construct the body of the PUT request.
' Note: If the From: header is included here,
' the MOVE method request will return a
' 403 (Forbidden) status. The From address will
' be generated by the Exchange server.
strText = "To: " & strTo & vbNewLine & _
"Subject: " & strSubject & vbNewLine & _
"Date: " & Now & _
"X-Mailer: test mailer" & vbNewLine & _
"MIME-Version: 1.0" & vbNewLine & _
"Content-Type: text/plain;" & vbNewLine & _
"Charset = ""iso-8859-1""" & vbNewLine & _
"Content-Transfer-Encoding: 7bit" & vbNewLine & _
vbNewLine & strBody

' Initialize the request.
bRequestSuccessful = False

' To use MSXML 3.0, use the following Set statement.
xmlReq = CreateObject("Microsoft.XMLHTTP")

' Open the request object by using the PUT method 
' and specify that it will be sent 
' asynchronously. The message will be saved 
' to the Drafts folder of the
' specified user's Inbox.
xmlReq.open("PUT", strTempURI, False, strUserName, strPassWord)

' Set the Content-Type header to the RFC 822 message format.
xmlReq.setRequestHeader("Content-Type", "message/rfc822")

' Send the request with the message body.
xmlReq.send(strText)

' The PUT request was successful.
If (xmlReq.Status >= 200 And xmlReq.Status < 300) Then
bRequestSuccessful = True
End If

' If the PUT request was successful,
' MOVE the message to the mailsubmission URI.
If bRequestSuccessful Then
' To use MSXML 3.0, use the following Set statement.
xmlReq2 = CreateObject("Microsoft.XMLHTTP")

' To use MSXML 4.0, use the following Set statement.
' Set xmlReq2 = CreateObject("Msxml2.XMLHTTP.4.0")

' Open the request object by using the PUT method and
' specify that it will be sent asynchronously.
xmlReq2.open("MOVE", strTempURI, False, strUserName, strPassWord)
xmlReq2.setRequestHeader("Destination", strSubURI)
xmlReq2.send()

' The MOVE request was successful.
If (xmlReq2.Status >= 200 And xmlReq2.Status < 300) Then
MsgBox("Message was sent to " & strTo & " successfully.")
End If
End If

' Clean up.
xmlReq = Nothing
xmlReq2 = Nothing

Compared to the CDOEX example, this WebDAV example is much more verbose. There is almost no support for setting friendly properties on objects in WebDAV. Instead, you must construct the PUT statement and manage the transport manually. This means that you spend more time coding and debugging than you do when you use an API that handles these functions internally.

EWS handles the transport seamlessly via the framework. You can precisely manage the details of each HTTP operation; however, in most cases, that is unnecessary.

Using Exchange Web Services to Send a Message

The following code example shows how to send a message by using Exchange Web Services.

ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new NetworkCredential("UserName", "Password", "Domain");
esb.Url = @"https://contoso.com/EWS/Exchange.asmx";

// Create a new message.
MessageType message = new MessageType();
        
// Define the e-mail address of the recipient of the message.
EmailAddressType singleRecip = new EmailAddressType();
singleRecip.EmailAddress = "ted@contoso.com";

message.ToRecipients = new EmailAddressType[1];
message.ToRecipients[0] = singleRecip;

// Set the subject and sensitivity properties.
message.Subject = "Siberian Tigers";
message.Sensitivity = SensitivityChoicesType.Personal;

// Set the body property.
message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.HTML;
message.Body.Value =
"Did you know there are estimated to be only about 400 " +
"of these magnificent creatures left in the wild?";

// Create a CreateItem request.
CreateItemType createItem = new CreateItemType();

// Specify that the CreateItem operation should directly send the message
// and save a copy in the Sent Items folder.
createItem.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
createItem.MessageDispositionSpecified = true;
        
DistinguishedFolderIdType folder = new DistinguishedFolderIdType();
folder.Id = DistinguishedFolderIdNameType.sentitems;

TargetFolderIdType targetFolder = new TargetFolderIdType();
targetFolder.Item = folder;
createItem.SavedItemFolderId = targetFolder;
         
createItem.Items = new NonEmptyArrayOfAllItemsType();
createItem.Items.Items = new ItemType[1] { message };
        
// Call the CreateItem method and get its response. 
CreateItemResponseType response = esb.CreateItem(createItem);

// Get the items returned by CreateItem.
ResponseMessageType[] itemsResp = response.ResponseMessages.Items;

In EWS, the CreateItem Web service method is overloaded. It is used to create any type of item (e-mail message, calendar item, and so on). The parameters that are passed define the type of item and the specific details that are required by that item. In this example, the parameters that are defined are specific to the definition of a message item. All calls in EWS follow the request/response structure. The response class provides a numeric value that indicates success or failure or provides a warning status for the request.

Stay Tuned

In part two of this series, I will provide calendaring examples that will show how to use Exchange Web Services to create an appointment. And don't forget about the final article in the series, which will include fully functioning sample applications that illustrate all the scenarios described in the series.