Training
Certifications
Books
Special Offers
Community




 
Programming Collaborative Web Applications with Microsoft® Exchange 2000 Server
Author Mindy Martin
Pages 912
Disk 1 Companion CD(s)
Level Intermediate
Published 07/12/2000
ISBN 9780735607729
Price $49.99
To see this book's discounted price, select a reseller below.
 

More Information

About the Book
Table of Contents
Sample Chapter
Index
Related Series
About the Author

Support: Book & CD

Rate this book
Barnes Noble Amazon Quantum Books

 


Chapter 6: CDO Messaging



Chapter 6 CDO Messaging

Remember when the fastest and easiest way to communicate with your coworkers in other offices and with colleagues at other companies was to pick up the telephone and call them? That wasn’t very long ago. Now, although the phone is still essential to doing business, e-mail has replaced it as our most important telecommunication link. Today when a phone system goes down, it’s a nuisance but not a disaster. (For that matter, many people now have cell phones.) However, when a messaging server goes down, the world seems to stop. Entire businesses come to their knees when e-mail isn’t working. People depend on this quick and easy form of communication for everything from handling standard business practices, such as invoice approvals, to providing the necessary link between international offices any time of the day.

More and more applications have messaging integrated into them. To keep up with this increasing demand, Collaboration Data Objects (CDO) for Microsoft Exchange 2000 Server provides a robust set of classes and interfaces to develop rich messaging applications. This chapter explains the core techniques necessary to build the simplest application or the most complex solution. Sections include:

  • Overview of CDO Messaging
  • Composing and Sending Messages
  • Composing More Complex Messages
  • Processing Messages

Overview of CDO Messaging

Microsoft Exchange 2000 Server and CDO support the Internet standards that specify how messages should be formatted for transmission across a network. By conforming to these standards, CDO for Microsoft Windows 2000 and CDO for Exchange can be used to build messaging solutions that function across a broad range of protocols, including Simple Mail Transfer Protocol (SMTP) and Network News Transfer Protocol (NNTP). The messages themselves are structured using Multipurpose Internet Mail Extensions (MIME), the currently accepted standard for messaging. This chapter focuses on MIME-formatted messages unless stated otherwise.

MIME enables any client program to decode and display complex message bodies, such as those that contain HTML tags, rich text, and structured attachments. MIME is highly flexible and allows each piece of an electronic mail message to be managed independently of, or in relation to, the other parts without affecting the underlying format of the message.


NOTE
Although the Microsoft Web Storage System is optimized for MIME and all messages are stored in MIME format by default, Exchange also supports the RFC 822 format and UUENCODE for attachments. RFC 822 is a simple message format consisting of header fields such as sender, recipient, and subject. This type of message might or might not have a body. If it does, it is separated from the header fields by an empty line. This type of message must consist of US-ASCII characters only.

CDO Messaging Classes and Interfaces

When you use CDO to build message applications, you use the classes and interfaces found in the CDO for Exchange 2000 object library (Cdoex.dll). Messaging applications are not built with a single object and interface but involve a number of classes and interfaces. The more complex the application, the more classes you use to create it. However, some basics always apply.

Predominant among these is the Message class. The Message class is the cornerstone of CDO messaging solutions. It can be either a message or a post, which is a message saved in a folder or posted to a newsgroup, and it is used to create new messages as well as to open and manipulate existing ones. The Message object has an extensive list of properties, but not all possible message fields are exposed as properties. The Message object also provides a Fields collection that you can use to access the schema properties that are not defined as CDO Message properties, including any custom properties. By using the methods of the Message object, you can send or post messages, reply to existing messages, and forward them to other recipients. You can address a message by using the properties of the Message object, but you must use the Addressee object to resolve addresses and eliminate ambiguous names. Figure 6.1 shows the Message object model.

If you work with MIME messages, then you will also use the BodyParts collection. MIME messages are made up of pieces known as BodyPart objects. A BodyPart can, for example, be an attachment, the body text, or the header section. You can create and manage attachments by using the BodyPart object. In addition, you can use the ActiveX Data Objects (ADO) Stream object to save attachments or other BodyPart objects to disk.

If you work with groups of messages, you will undoubtedly use the Configuration object. You use the Configuration object to define how to send or post a message. You can then apply that single configuration to all messages that your application sends, eliminating the need to configure each individual message. And, as with all CDO objects, the IDataSource interface handles the data swapping between the actual resource in the Microsoft Web Storage System and the copy of data in the CDO object.

Click to View Graphic.
Click to View Graphic

Figure 6.1 The CDO Message object model

Dissecting a MIME Message

To successfully build messaging applications by using CDO, you must understand how MIME messages are split into BodyPart objects. BodyPart objects have a media type property (BodyPart.ContentMediaType) that identifies what the BodyPart object contains. This section presents general information about media types. For a more detailed discussion of media types, see "Identifying the Media Type of a BodyPart Object" later in this chapter.

One way to learn how messages are broken into BodyPart objects is to step through a few messaging scenarios. A simple example is a plain-text message that has an attachment. When you create a simple message that uses plain text in the body text, the entire Message object is considered to be a single BodyPart object (see Figure 6.2). The BodyPart contains all the information about the message, including header information and the body text of the message. The BodyPart for the message has a media type of "text/plain."

Click to View Graphic.
Click to View Graphic

Figure 6.2 A plain-text message has only one BodyPart object and contains both the message header and the body text.

When you add an attachment, for example, a Microsoft Word document, to that message, the entire structure of the message changes. The message no longer has a single BodyPart object but three BodyPart objects: one for the header information, one for the attachment, and one for the body text. The BodyPart object that represents the header information is considered the parent of the other two BodyPart objects, which constitute a BodyParts collection. The BodyPart object that represents the body text is still plain-text, so it has a media type of "text/plain." The attachment is a Word document, so the media type for that BodyPart object is "application/msword." Because the message BodyPart object contains BodyPart objects with different media types, the message header BodyPart has a media type of "multipart/mixed." Figure 6.3 shows how the message evolves from a single BodyPart object into three BodyPart objects.

Click to View Graphic.
Click to View Graphic

Figure 6.3 A plain-text message with a Word document attachment has three BodyPart objects: one for the message header, one for the body text, and one for the file attachment.

Another example is a message with HTML formatting in the body text. Because not every client is able to process HTML in messages, by default Exchange also generates a plain-text version of the content. In this message, the body text must be rendered in two different BodyPart objects: one BodyPart object that represents the HTML version with a media type of "text/HTML" and one BodyPart object that represents the plain-text version with a media type of "text/plain." Because the message can generate the body text using two different formats, the message header BodyPart object has a media type of "multipart/alternative." Figure 6.4 shows this type of message structure.

Click to View Graphic.
Click to View Graphic

Figure 6.4 A message that uses both plain-text and HTML body text formats consists of three BodyPart objects: one for the message header, one for the plain-text format, and one for the HTML format.

Let’s look at one last example: this time, you want to create a message with HTML formatting in the body text and a Word document attachment. Essentially, this example combines the first two examples. When you create a message with two possible formats for the body text, the message has the same structure as that shown in Figure 6.4. When you add the attachment, the message becomes rather complex. The message BodyPart contains a BodyParts collection that consists of another BodyParts collection for the body text formats and a BodyPart object for the file attachment. Because the message contains multiple media types, the message header BodyPart has a media type of "multipart/mixed." The BodyParts collection that represents the body formatting types has a media type of "multipart/alternative" and consists of a BodyPart object for the HTML format with a media type of "text/HTML" and a BodyPart object for the plain-text version with a media type of "text/plain." The BodyPart object that represents the attachment has a media type of "application/msword". Figure 6.5 shows this nested multipart message.

Click to View Graphic.
Click to View Graphic

Figure 6.5 A message that uses alternative body text formatting and also includes a file attachment

Although this might seem rather overwhelming, the good news is that CDO provides several properties and methods to make your interaction with BodyPart objects and BodyParts collection as painless as possible. For example, when you add an attachment, you do not have to add a BodyPart object to the message and set the media type. Instead, you can use the AddAttachment method, which does the dirty work for you.

Composing and Sending Messages

Whether you’re composing a simple message with plain text or a complex message that uses a Web page in the body and a persistent configuration, you need to know the basic techniques involved in composing and sending a message. If you understand the basics behind messaging with CDO, the more advanced tasks don’t seem so advanced.

Sending a Simple Message

When you send e-mail to someone by using a client application such as Microsoft Outlook Web Access, you create a new message, fill in some information, and then send it. Typically, you address the message to someone, specify the subject matter, and fill in the body with the message. When you send a message with CDO, you do the same thing. To send a simple message by using CDO, create a new Message object and then:

  • Address the e-mail message. You can use the To, From, and CC properties to indicate who will receive the message. You set each property to a string value consisting of one or more e-mail addresses. If you use multiple e-mail addresses, separate each with a comma.
  • Specify the subject matter. You set the Subject property to a string value to a short description of the overall content of the message.
  • Fill in the body with some text. The body can contain plain text, HTML-formatted information, hyperlinks, or even complete Web pages. If you don’t need any formatting, you can use the TextBody property or HTMLBody property to fill the body of the e-mail with the message content. The TextBody property uses plain-text formatting in the body, and the HTMLBody property uses HTML formatting.
  • Send the e-mail message. When you are ready to send the e-mail, you use the Send method of a Message object.


NOTE
The code listings in this chapter are available in the project CH_06.vbp on the companion CD. The code samples in this chapter repeatedly call a function named GetStorageName. This function returns the name of the domain in which the code is running. For more information about the GetStorageName function, see Chapter 8, "Interacting with Active Directory."

When you send e-mail using CDO, you must do one additional thing to successfully send the message. You must specify who is sending the e-mail. Client applications such as Outlook Web Access do this for you automatically, but you must set this information explicitly when using CDO. You can set the From property of a Message object to do this. Listing 6.1 shows how to successfully send a very simple e-mail message to two people.

Listing 6.1. Send a simple message. 

Public Sub CreateandSendMail()
   ' This sends a very simple message
   
   ' If you are using VBScript, use this With:
   ' With CreateObject("CDO.Message")
   With New CDO.Message
      ' Indicate who is sending the message
      .From = "mindy@domain.com"

      ' Address the message
      .To = "denise@domain.com, aidan@domain.com"
      
      ' Set the subject matter
      .Subject = "Siberian Tigers"
      
      ' Fill in the body text using plain text formatting
      .TextBody = "Did you know there are estimated only " & _
         "about 400 of these magnifcent creatures left in the wild?"
      
      ' Send the message
      .Send
   End With
   
   Debug.Print "Message sent."
End Sub

Addressing a Message

When you develop an application by using the Microsoft Outlook 2000 object model or earlier versions of CDO, you address a message by adding to a Recipients collection of the message. CDO does not use a Recipients collection. Instead, when using CDO, you address a message by setting the appropriate CDO properties or schema properties to the appropriate e-mail addresses. The term "recipient" is still used; however, it only defines the receiver of a message. It does not define an object in the CDO object model.


NOTE
A CDO Addressee object represents each e-mail address added to the message. You can use the Addressee object to resolve an address, handle ambiguous addresses, and return the free/busy status of a user. However, you do not use the Addressee object to address a message.

Specifying Who Is Sending the Message 

As mentioned earlier, you must specify who is sending the e-mail message to successfully send it. You can indicate the sender by setting the From property to the e-mail address of the person who is sending the message. If you set the From property to more than one address, the first address is used as the From address. If you do not indicate a sender, the code fails with a trappable error. For example, this sets the From property for a Message object:

msg.From = "mindy@domain.com"

If you are sending multiple messages in the same application, you might want to specify a sender with a Configuration object instead of setting the From property on every Message object. By using a persistent Configuration object, you can define a sender with one object and then apply this Configuration to each message. For more information on using a Configuration object to set the sender information, see "Using a Persistent Configuration Object," later in this chapter.

Specifying Who Is Receiving the Message 

To indicate who is receiving the message, set one or more of the properties listed in Table 6.1. You can set each property to a string value that consists of one or more e-mail addresses.

Table 6.1 Standard address properties

CDO propertyData typeDescription
ToStringSets or returns the e-mail addresses for the primary recipients of the message.
CCStringSets or returns the e-mail addresses for the recipients of a courtesy copy of the message.
BCCStringSets or returns the e-mail addresses for the recipients of a courtesy copy of the message as a hidden list.

If you are sending to more than one address, separate each address with a comma. This style of creating multiple recipients is different from that used by some e-mail clients, including Outlook. The following code sample addresses an e-mail message to several recipients:

msg.To = "denise@domain.com, aidan@domain.com"
msg.CC = "robert@domain.com"
msg.BCC = "peter@domain.com"

CDO supports e-mail addresses in any address format defined by Internet standards. If you are sending a message within your organization, you can use the alias associated with an e-mail address. An alias is a shortcut name for the proper e-mail address and is often the portion of the e-mail address before the @ symbol. For example, an e-mail address of mindy@domain.com might have an alias of "mindy." 

Configuring for Replies 

In addition to setting the standard address properties for addressing a message, you can also set an alternative address for replies. Normally when you reply to an existing message, the replies go to the address specified in the From property. If you prefer to have replies sent to another address instead, set the ReplyTo property to that e-mail address. Replies then go to the ReplyTo address instead of to the From address.

As with the From property, the ReplyTo property has an equivalent configuration schema property that can be set with a Configuration object instead of setting the ReplyTo property on every Message. By using a persistent Configuration object, you can define the address used for replies with a single Configuration object and then apply this Configuration to each message. For more information about using a Configuration object to set the sender information, see "Using a Persistent Configuration Object," later in this chapter.

Adding the Body Text

You can add the body text of a message several different ways. You can add text that uses plain-text formatting, HTML formatting, or MIME Encapsulation of Aggregate HTML Documents (MHTML) formatting. This section discusses how to use these three types of formatting in the body text of a message.

Using Plain-Text Formatting 

If you want to add only simple text to the body of a message, set the TextBody property of a Message object to a text string. You can use the TextBody property to add text, but it does not allow you to specify special formatting, such as making some words bold or making bulleted lists. For example, the following code sample adds text to a Message object text body without using any special formatting:

msg.TextBody = _
    "This is the main body text without any special formatting."

If you want to format the text, you must use HTML to add the formatting features. 

Using HTML Formatting  

If you want to include formatting in the body text, you can use HTML formatting. With HTML, you can specify the font style, add bold or italic, or use bulleted lists. In fact, you can use just about any formatting available in HTML. To use HTML formatting in body text, you set the HTMLBody property to a legitimate HTML string. For example, the following code sample uses HTML formatting to create body text with a header, a rule, italic, and special font styles in the text:

msg.HTMLBody = _
   "<H1>Check this out!</H1>" & _
   "<HR><i>Look</i>" & _
   " at this " & _
   "<font color=red size=12>cool</font>" & _
   " HTML message."

When you create an HTML body, by default CDO also generates a plain-text version of the body text. The plain-text version of the body uses the same text as the HTML body but without any special HTML formatting. This ensures that clients unable to process HTML-formatted messages can still read the message. If you would rather not automatically generate a plain-text version of the body text, set the AutoGenerateTextBody property to False. Then, if you prefer to create a plain-text body, you can do so by setting the TextBody property to the value you want. For example, Listing 6.2 shows how to create a message with two different formats for the body text.

Listing 6.2 Generate a message with both a text body and an HTML body. 

Public Sub CreateSeparateTextandHTML()
   ' Use both an HTML and plain text
   ' version for body text formatting.
   
   ' If you are using VBScript, use this With:
   ' With CreateObject("CDO.Message")
   With New CDO.Message
      .From = "mindy@domain.com"
      .To = "peter@domain.com"

      .Subject = _
         "This message has two different body text versions"
      
      ' Generate body text for plain text viewers
      .TextBody = _
         "You're missing out by not supporting HTML!"
      
      ' Generate body text for HTML capable viewers
      .HTMLBody = _
         "<H1>Check this out!</H1>" & _
         "<HR><i>Look</i>" & _
         " at this " & _
         "<font color=red size=12>cool</font>" & _
         " HTML message."
      
      ' Send the message
      .Send
   End With
   
   Debug.Print "Message sent."
End Sub

Using MHTML Formatting 

Many e-mail clients, such as Outlook, can display HTML pages just like a Web browser does. To include all the HTML formatting, graphics, objects, and other elements contained in the Web page in the body of a message, you use MHTML formatting. MHTML is an Internet standard that defines the MIME structure that is used to send HTML content in message bodies along with those elements that are used in the Web page.

To embed a Web page or portions of a Web page as body text, you use the CreateMHTMLBody method of a Message object. The CreateMHTMLBody method has one required parameter: the URL of the Web page must be embedded in the body of a Message object. For example, the following code sample fills the body of a message with the msdn.Microsoft.com/exchange developer center home page:

msg.CreateMHTMLBody "http://msdn.microsoft.com/exchange/"

If the Web page contains support elements (such as sound files, style sheets, or graphics), they are included with the Web page and attached to the message as file attachments. Although this allows a recipient to view the Web page in its entirety, it also dramatically increases the size of a message in bytes. To avoid this increase in message size, you can use the optional argument Flags to indicate which elements to exclude. To define which elements to exclude, set the Flag parameter to one or more of the numeric constants from Table 6.2.

Table 6.2 Constants for the Flags argument of the CreateMHTMLBody method

CDO constantValueResult
cdoSuppressAll31Do not include support files.
cdoSuppressBGSounds2Do not include sound files.
cdoSuppressFrames4Do not include framesets.
cdoSuppressImages1Do not include image files.
cdoSuppressNone0Include all support files. (Default)
cdoSuppressObjects8Do not include object files.
cdoSuppressStyleSheets16Do not include style sheets.

The following code sample once again embeds the microsoft.com home page in a message, but this time, suppresses the background sounds and objects:

msg.CreateMHTMLBody _
    "http://msdn.microsoft.com/exchange/", _
    cdoSuppressImages + cdoSuppressObjects

Listing 6.3 shows how to embed a complete Web page into the body of an e-mail message while suppressing background sounds and objects used in the Web page.

Listing 6.3 Embed a Web page in the body of an e-mail message. 

Public Sub FillMessageBodywithWebPage()
   ' Creates a mail message with the Microsoft home page
   ' as the body text.

   Dim cnfg As CDO.Configuration
   
   ' Set the Sender information
   Set cnfg = New CDO.Configuration
   With cnfg
      .Fields(cdoSendEmailAddress) = "peter@domain.com"
      .Fields.Update
   End With
   
   ' Create the new message
   With New CDO.Message
      Set .Configuration = cnfg
      .To = "mindy@domain.com"
      .Subject = "This is a great web site."
      
      ' Embed the Microsoft home page into the body
      .CreateMHTMLBody _
         "http://msdn.microsoft.com/exchange/" _
         , cdoSuppressBGSounds + cdoSuppressObjects
      
      .Send
   End With
   
   ' Clean up
   Set cnfg = Nothing
End Sub

Figure 6.6 shows the result of executing the code in Listing 6.3. 

Click to View Graphic
Click to View Graphic

Figure 6.6 The CreateMHTMLBody method of a Message object lets you embed an entire Web page in the body of a message.

Adding Attachments

You often need to send files along with an e-mail message. To add an attachment, use the AddAttachment method of a Message object. The AddAttachment method is a shortcut to manually add a new BodyPart to a message and then set the necessary properties for that BodyPart to be an attachment. In case you need to manipulate the attachment further, the AddAttachment method returns a BodyPart object.

To use the AddAttachment method, pass a string value with the path and file name to be attached. An attachment can be a file on a local or remote computer, a message in an Inbox, or even a Web page. Correct examples of using the AddAttachment method include:

msg.AddAttachment _
   "D:\Sales Information\Latest Sales Data.xls"

msg.AddAttachment _
   "http://cyberserver/exchange/mindy/inbox/siberian%20tigers.eml"

msg.AddAttachment _
   "/index.html"

If the attachment doesn’t exist, the code fails with a trappable error. Listing 6.4 shows how to attach a file to a message. If the file doesn’t exist, an error message is generated.

Listing 6.4 Attach a file to a message. 

Sub CreateMsgwithAttachment()
   ' Attempts to attach a file
   ' to a message.
   
   ' Turn on error handling
   On Error GoTo HandleErrors
   
   ' Create a new message
   With New CDO.Message
      .From = " mindy @domain.com"
      .To = "peter@domain.com"
      .Subject = "Message with attachments"
      .TextBody = "Can you see this?"
      
      ' Attempt to attach a file
      .AddAttachment "D:\somefile.xls"
      
      ' Send the message
      .Send
   End With
   
   Debug.Print "Message sent."

ExitHere:
   Exit Sub
   
HandleErrors:
   Dim strError As String
   ' Get the error number, description, and source
   strError = "Error #" & Err.Number & ": " _
       & Err.Description
   ' Display the errors in a message box
   MsgBox strError
   Resume ExitHere
End Sub

Useful Schema Properties for Messaging

When you create a new CDO Message object, you are creating a resource in a Web Storage System with a DAV:contentclass of urn:content-classes:message. The Web Storage System automatically associates a number of properties with the urn:content-classes:message content class, most of which are accessible through a CDO property. However, some of the most useful schema properties cannot be read or set through a CDO property. Table 6.3 lists these schema properties.

Because a CDO object does not explicitly expose these properties, you must use the Fields property of a Message object to set them. You can pass either the schema property name or the CDO constant equivalent. After you set the appropriate properties, save the changes you made with the Fields.Update method. For example, the following code sample sets the importance level of the message to high:

Set msg = New CDO.Message
msg.Fields(cdoImportance) = cdoHigh

Table 6.3 To retrieve these schema properties for a Message object, you must use the Fields collection.

Schema propertyCDO constantData typeRead/write?Description
DAV:parentnamecdoParent NameStringNoURL of the container that owns the message.
DAV:hrefcdoHrefStringNoURL of the message that includes the display name.
DAV:ishiddencdoIsHiddenBooleanYesIf True, the message is not visible.
DAV:isreadonlyN/A1BooleanYesIf True, the message is read-only.
DAV:creationdatecdoCreation DateDateNoDate the message was created.
DAV:getcontentlengthN/ALongNoSize of the message.
DAV:displaynamecdoDisplay NameStringNoSubject of the message with the .eml extension.
DAV:uidcdoUIDStringNoUnique identifier value assigned by Exchange.
urn:schemas:httpmail:datecdoDateDateYesDate the message was sent to the server.
urn:schemas:httpmail:datereceivedcdoDate ReceivedDateNoDate the message was received by the server.
urn:schemas:httpmail:hasattachmentcdoHas AttachmentBooleanNoIf True, the message contains attachments.
urn:schemas:httpmail:importancecdo ImportanceLongYesImportance level: cdoLow (0)cdoNormal (1)cdoHigh (2).
urn:schemas:httpmail:readcdoReadBooleanYesIf True, the message has been read.
urn:schemas:httpmail:submittedcdo SubmittedBooleanYesIf True, the message has been sent to the Outbox for delivery.
urn:schemas:httpmail:thread-topiccdoThread TopicStringYesThe topic in a discussion thread.
urn:schemas:mailheader:message-idcdoMessage IdStringYesA unique identifier for a message.
urn:schemas:mailheader:receivedcdoReceivedStringNoAll the received headers for a message in one string.

1Not available.


Next




Top of Page


Last Updated: Friday, July 6, 2001