Click here to Skip to main content
13,357,610 members (63,800 online)
Click here to Skip to main content
Add your own
alternative version


27 bookmarked
Posted 7 Sep 2005

How to make a mail enabled contact in C#

, 22 Sep 2005
Rate this:
Please Sign up or sign in to vote.
This little article explains how to make a mail enabled contact in C#.


I spent quite a while finding and converting code-snippets to make an e-mail enabled contact. It seemed to me like it should be a relatively easy task to carry out, but I was missing the intricacies of CDO vs. ADSI users. There is a tech-note on Microsoft which is quite clear, but you have to have a bit of CDO experience to decode what it means. The tech-note is available here.

The key pieces of information are:

  1. You cannot use ADSI or an ADSI object to create a Mail Enabled anything.
  2. You must use CDO and CDOEXM and ADODB.
  3. You can only develop this on an Exchange server.
  4. You can only deploy it on an Exchange server.

The tech-note states that you can develop it on a Win200x machine with the Admin tools installed. This does not work. The reason is that the ADODB lib from Admin tools are not compatible with ADODB on .NET. You get a nasty error when trying to add a reference to CDOEXM with Admin Tools only. On a real Exchange Server, this does not seem to be a problem.

Eventually I downloaded the Exchange 2003 SDK and found the VB code for making a Mail Enabled Person. I then converted that into C#. That code can be found at MSDN.

A fairly serious fault I found with the original code one day later was that you must make sure that there will be no duplicate addresses in your domain. People were getting NDR reports, because of duplicate e-mail addresses.

LDAP could be used to repopulate so many things, and there are many attributes that contain e-mail addresses, that I was not sure how to test for "exchange enabled". Searching Proxy Addresses seemed to be a good way, because I read on tech boards that Proxy Addresses is what Exchange looked up to send email addresses. I found a relative tech-note that seemed to support this idea.

The way I chose to do it was to search all objects (this really takes a lot of processor and time). Because you can have mail enabled folders, contacts, persons, etc... I thought this the best way, as you might have "mail enabled" toasters ending up in Active Directory sometime in the future:, you never know.

As far as function naming goes, I always like to ask questions in the positive so the code reads easier (in my opinion). I think it is more understandable to write:

if (! EmailAddressExistInLDAP( "bsmith@mycompany", strRootDSE)

than to write:

if ( NotInAddressBook( ... ))

When you want to write the opposite, the logic can be difficult to follow.

if ( ! NotInAddressBook( ... ))

However in this case it does mean the function returns "true" to not add the contact, and that might be confusing reading the EmailAddressExistInLDAP through the first time.

This code takes about 5 minutes to run with the 600 contacts I am transferring so the *emailaddress* is an "expensive" way to go about it. If anyone knows something faster and better, I certainly would be interested.

Obviously as with all other freeware code in the world, this is as is and I recommend that you test it thoroughly in a development environment before releasing it on the real world.

You will also need to have created an ADSI contact, before this can MailEnable that contact. There are lots of code articles around about making a mail enabled contact.

Here is the code snippet:

using CDOEXM;
// strLDAPcn is an LDAP URL "LDAP://cn=Bill Smith,
//           ou=Connecticut,ou=Partners,DC=mynetwork,DC=com"
// strMailAddress is an valid Exchange
//      address "
// strRootDSE is the Root DSE Example "DC=mynetwork,DC=com"

private bool MailEnablePerson(string strLDAPcn, 
             string strMailAddress, string strRootDSE)
    // Create a CDO Person and a Recipient Object
    CDO.Person cdoPerson = new CDO.PersonClass();
    CDOEXM.IMailRecipient cdoRecipient;
    bool bRetVal = false;
    // set the parameters and fetch the user.  The contact must already exist.  
    // Cast the person onto the recipient 
    cdoRecipient = (IMailRecipient) cdoPerson;
    // If the user already has an SMTP mail property,
    // don't Email Enable them. 
    // "SMTPmail", is normally set by exchange
    // where the property "email" is 
    // the one that is in use from a contact.

    if (cdoRecipient.SMTPEmail == "")
        // If the user does not  have an SMTP address in LDAP then MailEnable them. 
        // The contact must already exist as an basic LDAP entry.
        if (! EmailAddressExistInLDAP(strMailAddress,strRootDSE) )
            // The key call to CDO, and then Save it
            // I am not sure why CDO.Person is saved but it was in the
            // Microsoft code, so I left it.
            cdoPerson.DataSource.Save() ; 
            bRetVal = true;
    return bRetVal ;
// EmailAdressExistInLDAP. As per the Technote,
// proxyAddresses = Exchange Email Addresses
// This takes two parameters
// strMailAddress the Email address example:
// strRootDSE the Root DSE example: DC=mycompany,DC=com
private bool EmailAddressExistInLDAP(string strMailAddress, 
                                         string strRootDSE)
    // Set the return value to True    
    // True means that the Active Directory would NOT be updated and
    // I prefer the default to be "don't do"     
    bool bRetVal = true;
    // Set a objSearch starting at RootDSE, and a place to return it.
    System.DirectoryServices.DirectorySearcher objSearch 
                    = new DirectorySearcher(strRootDSE);
    System.DirectoryServices.SearchResult objResult;
    // Filter only on the proxyAddress
    objSearch.Filter = "(& ( proxyAddresses=*"+strMailAddress+"*))";
    // if we even find one, we can't add another.
    // This is a slow way to look, but
    // it is better than having two Exchange Proxy
    // Address's and getting NDR's.
    objResult = objSearch.FindOne();
    if (objResult == null)
        bRetVal = false;
    return bRetVal;



This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Bermuda Bermuda
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralA simpler solution avoiding the use of ADODB Pin
rotorua21-May-09 12:39
memberrotorua21-May-09 12:39 
GeneralInvalidCastException Pin
Josh Hawley27-Sep-07 18:23
memberJosh Hawley27-Sep-07 18:23 
GeneralRe: InvalidCastException Pin
mapleleafsfan28-Sep-07 3:57
membermapleleafsfan28-Sep-07 3:57 
AnswerRe: InvalidCastException Pin
mapleleafsfan28-Sep-07 4:00
membermapleleafsfan28-Sep-07 4:00 
GeneralRe: InvalidCastException Pin
Josh Hawley28-Sep-07 13:00
memberJosh Hawley28-Sep-07 13:00 
GeneralCDOEXM Manipulation Pin
M. J. Jaya Chitra7-Oct-07 19:19
memberM. J. Jaya Chitra7-Oct-07 19:19 
Dear Mapleleafsfan,
I have some clarification. Can you please clarify the same.

1. What is CDOEXM? Is it a namespace? Where can I get it

Can you please suggest me a link which specifies how to contact and send mail to Exchange Server?

It is very very urgent task.

Best Regards,
M. J. Jaya Chitra

GeneralCDO.Person Pin
shashankkadge13-Aug-07 12:11
membershashankkadge13-Aug-07 12:11 
GeneralRe: CDO.Person Pin
mapleleafsfan13-Aug-07 17:24
membermapleleafsfan13-Aug-07 17:24 
GeneralRe: CDO.Person Pin
shashankkadge14-Aug-07 3:38
membershashankkadge14-Aug-07 3:38 
GeneralA Thanks, and a Comment Pin
Roger CS14-Jan-07 8:04
memberRoger CS14-Jan-07 8:04 
GeneralBad Filter Pin
jordi_gonzalez28-Sep-05 22:50
memberjordi_gonzalez28-Sep-05 22:50 
QuestionWhat includes are you using? Pin
blinkowski7-Sep-05 12:55
memberblinkowski7-Sep-05 12:55 
Answer[Message Deleted] Pin
mwdiablo7-Sep-05 13:21
membermwdiablo7-Sep-05 13:21 
GeneralRe: [Msg Deleted] Pin
Anonymous13-Sep-05 16:40
sussAnonymous13-Sep-05 16:40 
AnswerRe: What includes are you using? Pin
mwdiablo7-Sep-05 13:24
membermwdiablo7-Sep-05 13:24 
AnswerRe: What includes are you using? Pin
devonsprings7-Sep-05 14:55
memberdevonsprings7-Sep-05 14:55 
AnswerRe: What includes are you using? Pin
devonsprings7-Sep-05 15:12
memberdevonsprings7-Sep-05 15:12 
AnswerRe: What includes are you using? Pin
devonsprings7-Sep-05 15:22
memberdevonsprings7-Sep-05 15:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180111.1 | Last Updated 22 Sep 2005
Article Copyright 2005 by mapleleafsfan
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid