C#: Getting All Emails From Exchange using Exchange Web Services

Email_OpsThis article demonstrates how to use Exchange Webservices (EWS), as found on Exchange 2007 SP1 and going forward, to extract email body, headers and other email related items without using or needed Outlook installed. Note this assumes you are using Visual Studio 2008 and C#.

Steps

  1. Download and install the EWS assemblies from Exchange Web Services Managed API and install the target version either 32 or 64. Please remember to note the directory which it gets installed to for it is needed later. Of note is that the install directory contains an excellent document Getting Started which has examples that show the capabilities of the web services.
  2. Create your project in Studio, the below example C# code targets a Console Application.
  3. Add a reference to Microsoft.Exchange.WebServices by browsing to the directory loaded in step 1 and selecting the  Microsoft.Exchange.WebServices.dll. Remember to add using Microsoft.Exchange.WebServices.Data; in your code.
  4. Add these lines of code to initialize the web service:
    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    
    //service.Credentials = new NetworkCredential( "{Active Directory ID}", "{Password}", "{Domain Name}" );
    
    service.AutodiscoverUrl( "First.Last@MyCompany.com" );

     

    • Line 1 : Create an Exchange Web Service instance specifying that we are targeting a specific version of Exchange.
    • Line 3 :   You may need to have a service account do your dirty work and this line uncommented out is your key to doing that.
    • Line 5 : We don’t specify an Exchange server, but auto discover it. The server may be clustered and this will get the best one for the job. We also specify the account’s mailbox to use.
  5. Once the service is up and running we can now get the emails found in the box. Here is how we do it:
    FindItemsResults<Item> findResults = service.FindItems(
       WellKnownFolderName.Inbox,
       new ItemView( 10 ) );
    
    foreach ( Item item in findResults.Items )
       Console.WriteLine( item.Subject );

     

    • Line 1 :  We call the service to find out about the mailbox.
    • Line 2 :  We are interested in the inbox only, but we could be interested in the calendar. This is where to specify those items.
    • Line 3 :  We only want 10 items…change that number for different results
    • Line 5:  Print out the items, we are only going to show the subject but there are other header items we could show.
  6. Run the program. If everything goes alright then we have gotten the top ten items of the mailbox.

That should get you started. Again check the Getting Started document which the install dropped into the install folder for more examples!

Share

65 Comments

  1. foamy says:

    Hi,

    Great article, helped me a lot :)

    I have a question: I’m using the Credentials property to authenticate before using the AutoDiscoverUrl method, but whenever I do, the mailbox that is returned belongs to the user I specified in the Credentials.
    E.g I specify Admin in the Credentials and user@domain.com in the AutoDiscoverUrl method. This will give me the Admin’s Inbox.
    How can I specify an Administrator account and still get some other mailbox based on the e-mail address I enter in the AutoDiscoverUrl method?

    Hope it makes sense. Thanks again :)
    /foamy

  2. omegaman says:

    Yes it does make sense and I wrote about it in my new blog article Tribal Knowledge: EWS C# Extract Alternate Email Address’ Mailbox HTH

  3. foamy says:

    Brilliant, that does exacly what I need :D

    You’re a diamond!

  4. If we use the EWS API and have to hard-code the Exchange version (ExchangeVersion.Exchange2007_SP1) – is our code going to break when we upgrade to Exchange 2010?

    Thanks-
    Kenneth

  5. omegaman says:

    Update: Yes I verified this with Microsoft it will work. The idea is that 2010 has a version of web services and that it will provide both versions 2010 and 2007 SP1. So older clients will not break

    Good question, I haven’t played with 2010 beta to answer that. I should load it up in an Hyper-V virtual on my server and test. I will investigate…

    But I believe that specifing ExchangeVersion.Exchange2007_SP1 one is simply saying at a minimum that the process want a version of exchange and if the server is 2010 it simply provides web services at that lower version. Hence older clients won’t break.

  6. Melanie says:

    Hi,

    When trying to run the code provided above I get the following error:

    “An unhandled exception of type ‘Microsoft.Exchange.WebServices.Data.AutodiscoverLocalException’ occurred in Microsoft.Exchange.WebServices.dll

    Additional information: The Autodiscover service could not be located.”

    Can you help with this please?
    Thanks

  7. omegaman says:

    Exchange must be version 2007 with SP1. Is your exchange that version?

    You may want to post this question to the Exchange Server Development forum. HTH

  8. Predrag says:

    Hello.
    Is there way to get all emails from all accounts in exchange server? Can I do it if I have admin (system) account credentials?

  9. Simon says:

    Hello!

    I’m doing a project where I have to get all unread e-mails from an inbox and I’ve tried to get this thing to work but I encountered a problem quite soon after starting. The error message I’m getting is this:

    “The type ‘System.TimeZoneInfo’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’.”

    The two possibilities to this error I’ve come up with is this, I haven’t got any web reference, I couldn’t get the installation of it to work, or the fact that I’m using Windows XP. Do you know what causes the problem and if you do, is there a way working around it?

    Thanks and all the best!

    Simon

  10. Steve Ronald says:

    Connection to the exchange server to read Calendar,

    CalendarFolder myCalendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar);

    responds:

    ErrorMissingEmailAddress

    This error indicates that you specified a distinguished folder ID in the request, but the account that made the request does not have a mailbox on the system. In that case, you must supply a Mailbox sub-element under DistinguishedFolderId.

    I haven’t a clue how to apply Mailbox sub-element under DistinguisedFolderId

  11. McKinney says:

    And here I was thinking I was going to have to break down and use MAPI. Thanks for this article!

  12. ouTThere says:

    wow, I wish I found this a couple months ago.
    I spent hours getting MAPI to work

    great stuff

  13. vikram says:

    Hi,
    I am doing a project in which I have to read all the bounce e-mail messages sent to a user. I am using EWS web reference from the IIS where Exchange 2007 is deployed. PLease let me know how to send the search to fetch the bounce e-mails which contains some attachment. Actually i want to get the name of the attachment file from the bounce e-mail, update the database that this file ie not sent and delete the found e-mails. please help me.

  14. SeeeD says:

    Thank you so much for the tutorial =)
    I’ve lost so much time at the Exchange SDK.

    But one thing:
    I do not use this method:
    service.AutodiscoverUrl( “First.Last@MyCompany.com” );

    It needs around 10 seconds, to get the URL.
    I’ve saved the URI and wrote it into the URL-Property.

  15. rajen shrestha says:

    How can I move to different folder, out of mail server folder or delete attachement from the exchange mail server?

    thanks

  16. Michael says:

    What if the in box is full?

  17. SKY says:

    but the process is working in VS 2008 not in 2005,how can i read all types of mails in VS 2005,can anybody help me….??

  18. Mahendra Take says:

    I am developing an application in which i want to subscribe to
    calender item of all the users of exchange server by using administrator credential.

    Any help will be appreciated.

  19. azurekudos says:

    Sorry I am bit new…where we have to install .msi in Exchange server

  20. Andrew says:

    From looking at the soap api, is there not a way to get who the email is from? I see to, cc, but no from. Exchange 2007 environment.

  21. Pravin says:

    Hello Simon,

    I got the same error:

    “The type ‘System.TimeZoneInfo’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′.”

    And I resolved it by adding a reference to System.Core, available in .Net tab.
    Just incase this helps someone.

    Cheers,
    Pravin

  22. Guy D says:

    Where can I find the Active Directory ID? And by domain do you mean the address I use to login to my email?

  23. Sanjay Patel says:

    i getting Error message while reading mail using URL

    “The response received from the service didn’t contain valid XML.”

    FindItemsResults findResults = service.FindItems(WellKnownFolderName.SentItems,new ItemView(10));
    foreach (Item item in findResults.Items)
    Console.WriteLine( item.Subject );

    why i get this error

  24. Jørgen says:

    I also Get the “The response received from the service didn’t contain valid XML.”

    Has this something to do with the Exchange webservice configuration?

  25. Nibedita Jena says:

    Hi,
    I have to connect Exchange Server 2007 SP2 and I’m using Visual Studio 2005 C#.Net. I’m trying to connect by MAPI. But till yet not got any article regarding this. Could You please suggest me the best way to do this? Is there any article which I can refer for it? Please suggest me ASAP. It’s urgent for me.

    Thanks in Advance.
    Regards,
    Nibedita Jena

  26. ashok says:

    Hi All,

    I am trying to download contacts (created in outlook) from exchange server and using WebDAV sql query for the same. I am able to download contact related information but I could not download IM address. The problem here is that the Namespace “urn:schemas:contacts” does not contain IM Address property. Has anyone tried downloading IM address of the contact?

  27. Anu says:

    hi,
    I am getting “Bed Gateway” error while trying to read teh inbox data.
    at line -> FindItemsResults findResults = service.FindItems( WellKnownFolderName.Inbox, new ItemView( 10 ) );
    Please let me know how to getrid of this.
    For this to work do we need excchange server permissions? i do have a domain account. I am giving the same account details in the code. but eventhough iam gettin “Bad Gateway” error. Please help me.
    I am back of this since 3days.

    Thanks in advance.

  28. vasu says:

    Hi, i tried with the
    service.AutodiscoverUrl(MyName1@domain.com);

    method and i am able to get all the inbox mails.

    if i try with
    service.AutodiscoverUrl(MyName2@domain.com);

    Still it is showing the first user(MyName1@domain.com) inbox mails.
    Could you please help me to resolve the issue.

  29. Tassisto says:

    Hi,

    I have an account with 2 mailboxes. Your code returns only the default mailbox of my account. Is it possible to select the other mailbox by its name (name = Postvak IT Helpdesk)??? Any help is appreciated.

    Thanks in advance.

  30. Conrad says:

    Hi, I received the following error (probably for obvious reasons) but is this because of my access or is there some setting on exchange that needs to be changed? I am after all just access my own mail account.

    The request failed. The remote server returned an error: (403) Forbidden.

  31. PaulE says:

    It would be worth noting that many of the properties of the Item object do not load when the Item object is created through FindItems(…). To read these first-class properties (such as Body), you must call item.Load() first.

  32. DJ Burb says:

    THANK YOU!!!!!! This is just what I needed

  33. Sudeep says:

    Thank you very much.
    One query though. How can i read mails if the exchange server is 2003?

  34. Gorgi says:

    You anybody please help in reading mail from user defined folder instead of inbox using EWS

  35. Pritam says:

    can I read my gmail account using ExchangeService class?

    Thanks in advance

  36. Dino says:

    Is there a functionality built-in in EWS to find the reply text in the email? In other words, EmailMessage.body will give you both reply and original message body. Any easy to separate them out so we know what is reply text?

  37. David says:

    Hello, I just found the answer for which I was looking. The way to remove all the items and subfolders is to use the boolean $true This is the way it should look. $Outbox.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::MoveToDeletedItems ,$true)

  38. srinivas says:

    i am not able to system.net.networkcredential namespace,how i will get
    please give me advice.

  39. Thomas Agustin says:

    HI,
    We are planning for calender syn for a business unit, i have calender names and i have to sync the all the calender events to the our data base. How do we achieve the same. What access we should grant to all these calenders? We have created a service account ans account has access to all the calenders. How can we read all the calannders using this sv account ?

  40. sam says:

    The Autodiscover service could not be located.

    i am getting this error.please help me.
    i have wasted quite a lot of time behind this.
    but i could not solve it.

    plssss

  41. karthik says:

    i am getting this error after connecting server

    The request failed. The remote server returned an error: (401) Unauthorized

  42. Beena says:

    Hi ,

    I am getting the below issue, while i create an appointment

    “The request failed. The remote server returned an error: (401) Unauthorized”.

    i am using below line to call server account,
    service.Credentials = new NetworkCredential(strFromID, strPwd, strDomain);

    It would be great help, if anyone faced the similar issue befor and the solution is sharable. Thanks in Advance.

    Regards,
    Beena Celin T.

  43. Mr Chris says:

    Not sure if anyone else has stumbled on this problem. Had this working fine until recently logging into and managing a couple of email accounts automatically. Then something must of changed and am now getting the following back when I utilise the service.autodiscover :

    Microsoft.Exchange.WebServices.Data.AutodiscoverLocalException: Autodiscover blocked a potentially insecure redirection to https://webmail.gilestravel.com/autodiscover/autodiscover.xml. To allow Autodiscover to follow the redirection, use the AutodiscoverUrl(string, AutodiscoverRedirectionUrlValidationCallback) overload.

    Anyone else had this issue?

  44. Mike says:

    I got this working just fine but can’t seem to find a way to retrieve the senders email address? Any thoughts?

  45. Mike says:

    Sorry I found what I was missing. Was not binding the item to an EmailMessage object. All is good now. Thanks for the previous examples they helped tremendously.

  46. yeshveer says:

    Hi All i have one questions
    can I read my gmail account using ExchangeService class?

    and i am getting an Error message while reading mail using URL

    “The response received from the service didn’t contain valid XML.”

    email.SendAndSaveCopy();
    over here why am i getting this when i am sending an email to myself

    Thanks in advance

  47. Pat Kash says:

    I am using the following code block to download attachments from the email and save to disk. But, if the attachment is an image file like JPG, it’s taking very long when executing the line fileAttachment.Load();

    if (attachment is FileAttachment)
    {
    FileAttachment fileAttachment = attachment as FileAttachment;

    using (FileStream theStream = new FileStream(“C:\\temp\\Stream_” + fileAttachment.Name, FileMode.OpenOrCreate, FileAccess.ReadWrite))
    {
    fileAttachment.Load(theStream);
    theStream.Close();
    theStream.Dispose();
    }
    }

    Do you have any suggestions for me to get this done in a more efficient way?

  48. Harish says:

    Hi ,
    I have delgate access to shared mailbox .And i want to access a usercreated folder(not standard folders) . The exchange server is 2010 so that i wont be able to use the below code

    FindItemsResults findResults = service.FindItems(new FolderId( folder.WellKnownFolderName.value ,mailBox)

    I am not able to impersonate also. using the below code

    ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, smtpAddress);

    Please advice

Leave a Reply