Read MS Exchange email in C#
It's a mess. MAPI or CDO via a .NET interop DLL is officially unsupported by Microsoft--it will appear to work fine, but there are problems with memory leaks due to their differing memory models. You could use CDOEX, but that only works on the Exchange server itself, not remotely; useless. You could interop with Outlook, but now you've just made a dependency on Outlook; overkill. Finally, you could use Exchange 2003's WebDAV support, but WebDAV is complicated, .NET has poor built-in support for it, and (to add insult to injury) Exchange 2007 nearly completely drops WebDAV support.
What's a guy to do? I ended up using AfterLogic's IMAP component to communicate with my Exchange 2003 server via IMAP, and this ended up working very well. (I normally seek out free or open-source libraries, but I found all of the .NET ones wanting--especially when it comes to some of the quirks of 2003's IMAP implementation--and this one was cheap enough and worked on the first try. I know there are others out there.)
If your organization is on Exchange 2007, however, you're in luck. Exchange 2007 comes with a SOAP-based Web service interface that finally provides a unified, language-independent way of interacting with the Exchange server. If you can make 2007+ a requirement, this is definitely the way to go. (Sadly for me, my company has a "but 2003 isn't broken" policy.)
If you need to bridge both Exchange 2003 and 2007, IMAP or POP3 is definitely the way to go.
Read Office365 emails from Exchange Server using .Net C# IMAP client
I resorted to using the Microsoft Exchange Web Service instead of IMAP.
Example:
using System;
using Microsoft.Exchange.WebServices.Data;
ExchangeService _service;
Console.WriteLine("Registering Exchange connection");
_service = new ExchangeService
{
Credentials = new WebCredentials(username, password)
};
// This is the office365 webservice URL
_service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties);
propSet.Add(ItemSchema.MimeContent);
propSet.Add(ItemSchema.TextBody);
foreach (EmailMessage email in _service.FindItems(WellKnownFolderName.Inbox, new ItemView(10)))
{
var message = EmailMessage.Bind(_service, email.Id, propSet);
Console.WriteLine("Email body: " + message.TextBody);
Console.WriteLine();
}
Reference
Note: this seems to be deprecated. Also, I am not sure if this uses Basic auth or not. I guess not, since that was supposed to stop working after October 2020 and I have just used this code for a quick test in July 2021.
Read Email Outlook 365 folder - EWS
You need to first find that TargetFolders FolderId and you can then do a search against that folder. There a few different ways people do this eg a few are outlined in Get to an Exchange folder by path using EWS
The method I always use is to feed in a Path and then a do shallow search to find the target folder eg GetFolderFromPath(service,"mailbox@domaim.com","\Inbox\folder")
internal static Folder GetFolderFromPath(ExchangeService service,String MailboxName,String FolderPath)
{
FolderId folderid = new FolderId(WellKnownFolderName.MsgFolderRoot,MailboxName);
Folder tfTargetFolder = Folder.Bind(service,folderid);
PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
String[] fldArray = FolderPath.Split('\\');
for (Int32 lint = 1; lint < fldArray.Length; lint++) {
FolderView fvFolderView = new FolderView(1);
fvFolderView.PropertySet = psPropset;
SearchFilter SfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName,fldArray[lint]);
FindFoldersResults findFolderResults = service.FindFolders(tfTargetFolder.Id,SfSearchFilter,fvFolderView);
if (findFolderResults.TotalCount > 0){
foreach(Folder folder in findFolderResults.Folders){
tfTargetFolder = folder;
}
}
else{
tfTargetFolder = null;
break;
}
}
if (tfTargetFolder != null)
{
return tfTargetFolder;
}
else
{
throw new Exception("Folder Not found");
}
}
c# programmatically reading emails from the Exchange server
You don't necessarily need to use the autodiscovery if you already know the address of your exchange server. Try the following instead (for more info, look here:
service.Url = new Uri("https://hostname/EWS/Exchange.asmx");
Replace "hostname" with the hostname for your exchange server.
How to access specific email from EWS exchange server
The IntenetMessageId should be unique but there is no guarantee that it will be because of the number of different processes that can set the Id's.
If you want to get a specific message based on its InternetMessageId then you need to use the Extended property rather then the strongly typed one eg
String MessageID = "<blah@1223434556com">"
ItemView ivew = new ItemView(3);
service.TraceEnabled = true;
ExtendedPropertyDefinition PidTagInternetMessageId = new ExtendedPropertyDefinition(4149, MapiPropertyType.String);
SearchFilter sf = new SearchFilter.IsEqualTo(PidTagInternetMessageId, MessageID);
FindItemsResults<Item> iCol = service.FindItems(WellKnownFolderName.Inbox, sf, ivew);
foreach (Item item in iCol.Items)
{
Console.WriteLine(item.Subject);
}
You can export the message to a EML file using https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-export-items-by-using-ews-in-exchange
Read emails from exchange online (Office 365) through windows forms application
Yes, you can do with with Exchange web service API. It is designed for client application. Follow the link, you can find a lot of examples.
One note is: to create the service client, you need specify the version of the Exchange Server, it should be ExchangeVersion.Exchange2013_SP1
for exchange online.
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
Related Topics
Why There Are 5 Versions of Timer Classes in .Net
How to Fix a Opacity Bug with Drawtobitmap on Webbrowser Control
How to Format a Datetime in a Different Format
Unity Singleton Manager Classes
Metadata File '.Dll' Could Not Be Found
Why Are Unsigned Int's Not Cls Compliant
Ef Including Other Entities (Generic Repository Pattern)
Does It Make Sense to Use "As" Instead of a Cast Even If There Is No Null Check
No Overflow Exception for Int in C#
How to Do Appbar Docking (To Screen Edge, Like Winamp) in Wpf
Does C# Optimize the Concatenation of String Literals