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 : "");
}
}
6 Comments
Adr
Hello,
Thanks for this post, but can you attach the source file ? Then we won't have to guesswhat references you have imported exactly.
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
jen
wouldn't it be easier to do service.ResolveName?
anset
Hello,
can you please specify what "URL" is ? At the first line,
i mean, can you give some example ? like to access hotmail
kk
kk
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