Click here to Skip to main content
15,868,141 members
Articles / Programming Languages / C#
Article

How to make a mail enabled contact in C#

Rate me:
Please Sign up or sign in to vote.
4.10/5 (6 votes)
22 Sep 20053 min read 77.1K   27   18
This little article explains how to make a mail enabled contact in C#.

Introduction

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: sendto:popup@mytoaster.com, 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:

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

than to write:

C#
if ( NotInAddressBook( ... ))

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

C#
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:

C#
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 "SMTP:bsmith@mypartnercompany.com
// 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.  
    
    cdoPerson.DataSource.Open(strLDAPcn,null,
        ADODB.ConnectModeEnum.adModeReadWrite,
        ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
        ADODB.RecordOpenOptionsEnum.adOpenSource,"","");
 
    // 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.
 
            cdoRecipient.MailEnable(strMailAddress);
            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: bsmith@mypartnercompany.com
// 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;
}

Links

License

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


Written By
Bermuda Bermuda
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralCDO.Person Pin
shashankkadge13-Aug-07 11:11
shashankkadge13-Aug-07 11:11 
GeneralRe: CDO.Person Pin
mapleleafsfan13-Aug-07 16:24
mapleleafsfan13-Aug-07 16:24 
GeneralRe: CDO.Person Pin
shashankkadge14-Aug-07 2:38
shashankkadge14-Aug-07 2:38 

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.