Exchange Recently, I had a need to access my contacts in outlook via a C# program.  Unfortunately, the different ways of accessing data via Exchange are woefully inadequate.  Interop requires that you are running Outlook when and where the program is run, and Exchange Web Services (EWS) are poorly documented and a pain in the ass to use.  Finding specific examples of what you want to do with EWS online is, literally, like finding a needle in a haystack.  After searching for some time, I came across this solution at Wes’ Puzzling Blog. Now the example here doesn’t do exactly what we want.  In his example, he’s actually looking for a specific contact named “Wes”.  We want to pull all of the contacts.  The first thing that I’d like to point out is that using the ExchangeServiceBinding requires a Sharepoint dll.  Yes, that’s right, a Sharepoint DLL!  Why this is, I’m unsure.  However, to save you the trouble of having to either find the dll or download and install Sharepoint just to get at the dll.  You can download the Exchange 2007 Microsoft.sharepoint.portal.dll here.  Once you’ve added a reference to that to your project, you must also reference System.Web.Services.  From there you just need a bit of C# code:

//Here the URL should be the url of our exchange asmx file
ExchangeServiceBinding esb = new ExchangeServiceBinding("URL");
//if you want to connect as a user other than who is running the program, change this
esb.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
//This section probably won't make a lot of sense.  What's important is that it's a request that
//will tell exchange we want to pull from the contacts folder
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType();
folderIDArray[0].Id = DistinguishedFolderIdNameType.contacts;
//If we're not accesisng the email box of the user who's running the program, specify it here
//folderIDArray[0].Mailbox = new EmailAddressType();
//folderIDArray[0].Mailbox.EmailAddress = "[email protected]";
// Send the request and get the response
FindItemResponseType findItemResponse = esb.FindItem(findItemRequest);
if (findItemResponse.ResponseMessages.Items.Length > 0)
{
    FindItemResponseMessageType responseMessage =
    findItemResponse.ResponseMessages.Items[0] as FindItemResponseMessageType;
    ArrayOfRealItemsType realItems =
    responseMessage.RootFolder.Item as ArrayOfRealItemsType;
    foreach (ContactItemType contact in realItems.Items)
    {
    // Do work with data returned for each contact
    Console.WriteLine(contact.EmailAddresses != null && 
        contact.EmailAddresses.Length > 0 ?
        contact.EmailAddresses[0].Value : "");
    }
}

So as you can see, the most complicated part of this is building the request and knowing where to look in the response.  All this will do is write out the email addresses of the contacts that are found, however, you should have access to all of the contact info you might need.

Chris Risner


6 Comments

Chris

Hi Adr,

I'll try and dig through my files and find my original source.  Sorry it wasn't attached at the time.  While I'm looking / in case I can't find it, is there a specific reference issue you're running into?  I believe if you add a reference to the Exchange 2007 dlls (linked above) to your project, Visual Studio should be able to help you add all the necessary references to your code files.

Chris

kk

I am getting error when I use System.Net.CredentialCache.DefaultCredentials instead of new NetworkCredential("user name", "pwd", "domain.com");
I want to read the emails of current logged in users
How to do it

Leave a Comment