This tips and tricks section provides some basic and also special tasks
for CDO 1.x and ASP. Note that the following examples should serve only as
an idea to create your own solution and are not checked for proper function.
You can find a lot of checked and proper running samples at the CDOLive
Code Sample Library.
Common Tasks
| Task |
Description |
| Check if a valid Microsoft Windows
NT session is established |
Before you can log on with CDO 1.x to a Microsoft Exchange
server 5.x mailbox you need to establish a valid Microsoft Windows
NT 4.x session. To check if a user is authenticated run the
following code in a server-side ASP script file:
If Request.ServerVariables("LOGON_USER") = "" Then
Response.Status = "401 Access Denied"
End If
If the LOGON_USER is blank, you are authenticated as
IUSR_<machine> and you can't open a mailbox without authenticate
properly. Otherwise, the LOGON_USER displays the <domain\user> name
of the authenticated user. |
| Log on anonymous |
To log on anonymously it is necessary to know the Microsoft
Exchange Organization (AKA Enterprise), Site and Server name. The
CDO Rendering library 1.x application object provides an
undocumented method to pull that information out of the Microsoft
Windows NT 4.x Registry of the server which has Microsoft Outlook
Web Access 5.x installed. The following code snippet shows how it is
done: ' Create renderer application
On Error Resume Next
Set objRenderApp = Server.CreateObject("AMHTML.Application")
' Pull configuration out of the registry
Err.Clear
On Error Resume Next
objRenderApp.LoadConfiguration 1,_ "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\_
MSExchangeWeb\Parameters" strEnterprise =
objRenderApp.ConfigParameter("Enterprise") strSite =
objRenderApp.ConfigParameter("Site") strServer =
objRenderApp.ConfigParameter("Server")
' Construct CDO
profile strProfileInfo = "/o=" + strEnterprise + "/ou=" +
strSite +_ "/cn=Configuration/cn=Servers/cn=" + strServer + vbLF
+ "anon" + vbLF + "anon"
' Create CDO session Err.Clear
On Error Resume Next Set objSession = Server.CreateObject("MAPI.Session")
' Logon with anonymous CDO profile Err.Clear On Error Resume
Next objSession.Logon "", "", False, True, 0, True,
strProfileInfo |
| Log on authenticated |
To log on authenticated it is necessary to provide only a
Microsoft Exchange Servername and a valid mailbox. The CDO Rendering
library 1.x application object provides an undocumented method to
pull the Microsoft Exchange Servername out, but not a valid mailbox.
The following code snippet shows how it is done:
' Set
render application On Error Resume Next Set objRenderApp =
Server.CreateObject("AMHTML.Application")
' Pull
configuration out of the registry Err.Clear On Error Resume
Next objRenderApp.LoadConfiguration 1,_
"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\_
MSExchangeWeb\Parameters" strServer =
objRenderApp.ConfigParameter("Server")
' If the Exchange
mailbox alias and the Windows NT UserID are the same, ' use the
following code to retrieve the DOMAIN\UserID from the IIS '
server variables and then manipulate the string to return just the
Windows ' NT UserID:
strLogonID = Request.ServerVariables("Logon_User")
strMailbox = Right(strLogonID, Len(strLogonID) - InStr(strLogonID,
"\"))
' Construct CDO profile strProfileInfo =
strServer + vbLF + strMailbox
' Create CDO session
Err.Clear On Error Resume Next Set objSession =
Server.CreateObject("MAPI.Session")
' Logon with
authenticated CDO profile Err.Clear On Error Resume Next
objSession.Logon "", "", False, True, 0, True, strProfileInfo |
| Open the public
information store |
After a session is successfully established the information
stores must be opened once to make sure everything is OK. Otherwise
it is possible that the session logon did not return an error but
the current session does not have permissions to open the particular
information store. The following code snippet shows how it is done
for public folders:
' MAPI properties to access the public
information store Const CdoPR_STORE_SUPPORT_MASK = &H340D0003
Const CdoPR_STORE_PUBLIC_FOLDERS = &H00004000
' We need to
force the store to open before anonymous access will work Set
objInfoStores = objSession.InfoStores For intCounter = 1 To
objInfoStores.Count Set objInfoStore = objInfoStores.Item(intCounter)
lMask = objInfoStore.Fields.Item(CdoPR_STORE_SUPPORT_MASK)
If lMask And CdoPR_STORE_PUBLIC_FOLDERS Then Exit For
End If Next
|
Special Tasks
| Task |
Description |
| Increase logging level for
debugging |
The CDO rendering library 1.x application object supports a
LoggingLevel property which controls how much information is written
to the event log. ' Get the current logging level for startup
category strLevel = objRenderApp.LoggingLevel(1)
The following categories are defined:
| Category |
Description |
| CATEGORY_STARTUP >or "1" |
Events that occur during the creation of the rendering
object |
| CATEGORY_GENERAL or "2" |
Events that occur while the rendering object is generating
HTML output |
| CATEGORY_CONTENT or "3" |
Unused |
| CATEGORY_SECURITY or "4" |
Unused |
| CATEGORY_INTERNAL or "5" |
Unused |
| CATEGORY_SHUTDOWN or "6" |
Unused |
The logging level construct is an array with five elements, one
for each logging category. Each element in the array can have a
value from 0 to 5, representing the logging verbosity for that
category.
' Set logging level for startup category to verbose
objRenderApp.LoggingLevel(1) = 4
The following logging levels are defined for each category:
| Level |
Description |
| 0 |
Critical – log only the most severe failure events
(default). |
| 1 |
Minimal – include nearly all error events. |
| 2 |
Basic – include certain important success events. |
| 3 |
Extensive – include most routine success events. |
| 4 |
Verbose – include all events not related to internal
workings. |
| 5 |
Internal – include events of interest only to users familiar
with the internal workings of the CDO Rendering Library. |
The default is level 0. It is the least verbose and logs only
the most severe errors for that logging category. Level 5 is the
most verbose and logs all events at all levels of severity. |
| Render the rich text body of a message |
The CDO rendering library 1.x contains an automatic RTF to HTML
conversion engine. With this feature it is possible to build rich
web pages with a single e-mail message. You can also use an HTML
message body (with Microsoft Outlook 98/2000) to maintain a complete
HTML page in a single message object. Use the following code snippet
to render the message subject and body:
' MAPI properties
for message subject and RTF text body Const CdoPR_SUBJECT =
&H0037001F Const CdoPR_RTF_COMPRESSED = &H10090102
' Create object renderer and set DataSource to message object
Set objRenderer = objRenderApp.CreateRenderer(2)
objRenderer.DataSource = objMessage
' Render the subject and message body into HTML code
objRenderer.RenderProperty CdoPR_SUBJECT, 0, Response
objRenderer.RenderProperty CdoPR_RTF_COMPRESSED, 0, Response
|
| Render the plain text body of a
message |
Sometimes you want to include a short description, stored in the
message body, in the table view of a container render. This is
possible by including the plain text body in the CDO Rendering
library 1.x container renderer columns collection:
' MAPI properties for message subject and plain text body
Const CdoPR_SUBJECT = &H0037001F Const CdoPR_BODY = &H1000001F
' Create container renderer and set datasource to message collection
Set objRenderer = objRenderApp.CreateRenderer(3)
objRenderer.DataSource = objMessages
' Create format and
add patterns Set objFormat = objRenderer.Formats.Add(CdoPR_SUBJECT)
Set objPatterns = objFormat.Patterns objPatterns.Add "*",_
"<font face='Arial, Helvetica, sans-serif' size='-1'>%value%</font>"
Set objFormat = objRenderer.Formats.Add(CdoPR_BODY)
objPatterns.Add "*",_ "<font face='Arial, Helvetica, sans-serif'
size='-1'>%value%</font>"
' Create view and set columns
Set objView = objRenderer.Views.Add("DefaultView") Set
objColumns = objView.Columns
' Add columns to view
objColumns.Add "Subject", CdoPR_SUBJECT, 30, 0, 0 objColumns.Add
"Description", CdoPR_BODY, 40, 32, 1 objRenderer.CurrentView = "DefaultView"
|
| Hide the heading row of a container renderer |
To build a powerful content management with public folders, it
might be a good idea to remove the default heading row of the
container render. If you include the following code nobody would
imagine that you manage your whole Intra/Internet content within
Microsoft Exchange server public folders:
' MAPI properties
for message class, delivery time and subject Const
CdoPR_MESSAGE_CLASS = &H001A001F Const
CdoPR_MESSAGE_DELIVERY_TIME = &H0E060040 Const CdoPR_SUBJECT =
&H0037001F
' Create view and set columns Set objView =
objRenderer.Views.Add("DefaultView") Set objColumns =
objView.Columns
' Add columns to view ' Note: do not remove the blank character
otherwise the heading row ' will end up in an undefined state
objColumns.Add " ", CdoPR_MESSAGE_CLASS, 1, 8, 1 objColumns.Add
" ", CdoPR_MESSAGE_DELIVERY_TIME, 18, 0, 2 objColumns.Add " ",
CdoPR_SUBJECT, 50, 32, 3 objRenderer.CurrentView = "DefaultView"
' Hide heading row ' Note: do not remove this lines otherwise
the heading row ' will become visible with the default color
objRenderer.HeadingRowPrefix = "<tr valign='top'>"
objRenderer.HeadingRowSuffix = "</tr>"
|
| Download an attachment |
It is possible to access the attachments of a particular
message. You just need to sent the binary data stream to the browser
like this:
' MAPI property for attachment binary data
Const CdoPR_ATTACH_DATA_BIN = &H3701010
' Set attachment filename If objMessage.Attachments.Count <> 0
Then Set objAttachment = objMessage.Attachments.GetFirst()
bstrFileName = objAttachment.Name End If
' Add the appropriate HTTP header to the response object
Response.AddHeader "Content-Disposition", "attachment;filename="_
+ bstrFileName
' Create object renderer and set DataSource to attachment object
Set objRenderer = objRenderApp.CreateRenderer(2)
objRenderer.DataSource = objAttachment
' Send the attachment data stream back to the browser
objRenderer.RenderProperty CdoPR_ATTACH_DATA_BIN, 0, Response
|
For a list of the most common MAPI property tags, please take a look
at 'Digging deeper into CDO', Property Tags
and Types or use the CDO.HLP file, which is located on the Microsoft
Exchange Server 5.5 CD-ROM. Note, that an updated version is included
with the Microsoft Exchange Server 5.5 Service Pack 1 (or higher). You
can also download the most current version from CDOLive
cdo.zip (1,065 Kbyte).