Ews Class
Provides properties and methods for working with e-mails on MS Exchange server via Exchange Web Services.
Inheritance Hierarchy
SystemObject
  MailBee.EwsMailEws

Namespace: MailBee.EwsMail
Assembly: MailBee.NET (in MailBee.NET.dll) Version: 12.4 build 677 for .NET 4.5
Syntax
public class Ews : IComponent, IDisposable

The Ews type exposes the following members.

Constructors
  NameDescription
Public methodEws
Creates an instance of Ews class.
Public methodEws(String)
Creates and unlocks an instance of Ews class.
Top
Methods
  NameDescription
Public methodAddAttachmentToItem
Adds an attachment to an existing item.
Public methodAddAttachmentToItemAsync
Public methodAutodiscover
Automatically determines the URL of the EWS server.
Public methodCopyItem
Copies the specified item (e.g. mail message) into the specified folder.
Public methodCopyItemAsync
Async/await version of CopyItem(ItemId, FolderId).
Public methodCreateFolder
Creates a folder in the MS Exchange account.
Public methodCreateFolderAsync
Async/await version of CreateFolder(String, FolderId).
Public methodCreatePropSet
Creates EWS Managed API PropertySet object.
Public methodDeleteAttachment
Deletes the attachment with the specified filename from the specified item.
Public methodDeleteAttachmentAsync
Public methodDeleteAttachments
Deletes all attachments in the specified item.
Public methodDeleteAttachmentsAsync
Async/await version of DeleteAttachments(ItemId).
Public methodDeleteFolder
Deletes a folder with the specified ID.
Public methodDeleteFolderAsync
Async/await version of DeleteFolder(FolderId).
Public methodDeleteItem
Deletes the specified item (e.g. mail message).
Public methodDeleteItemAsync
Async/await version of DeleteItem(ItemId).
Public methodDeleteItems
Deletes the specified item (e.g. mail message).
Public methodDeleteItemsAsync
Public methodDispose
Closes all opened network connections (if any) and releases any used system resources.
Protected methodDispose(Boolean)
When overridden in a derived class, must release unmanaged and optionally managed resources used by the component.
Public methodDownloadEntireMessage
Downloads the specified item by its ID and returns it as MailMessage object.
Public methodDownloadEntireMessageAsync
Async/await version of DownloadEntireMessage(ItemId).
Public methodDownloadFolderByFullName(String)
Gets the reference to the folder denoted by its full name in the MS Exchange account.
Public methodDownloadFolderByFullName(FolderId, String)
Gets the reference to the given folder in the specified containing folder in the MS Exchange account.
Public methodDownloadFolderByFullName(String, Int32)
Gets the reference to the folder denoted by its full name in the MS Exchange account.
Public methodDownloadFolderByFullNameAsync(String)
Async/await version of DownloadFolderByFullName(String).
Public methodDownloadFolderByFullNameAsync(FolderId, String)
Public methodDownloadFolderByFullNameAsync(String, Int32)
Async/await version of DownloadFolderByFullName(String, Int32).
Public methodDownloadFolderById(FolderId)
Gets the reference to the folder with given ID in the MS Exchange account.
Public methodDownloadFolderById(FolderId, PropertySet)
Gets the reference to the folder with given ID in the MS Exchange account, also requesting the specified properties.
Public methodDownloadFolderByIdAsync(FolderId)
Async/await version of DownloadFolderById(FolderId).
Public methodDownloadFolderByIdAsync(FolderId, PropertySet)
Public methodDownloadFolderByShortName
Gets the reference to the given folder in the MS Exchange account.
Public methodDownloadFolderByShortNameAsync
Public methodDownloadFolders(Boolean)
Downloads the list of folders of the MS Exchange account.
Public methodDownloadFolders(FolderId, Boolean, Boolean)
Downloads the list of folders of the MS Exchange account.
Public methodDownloadFolders(FolderId, FolderView, SearchFilter, Boolean)
Downloads the list of folders of the MS Exchange account.
Public methodDownloadFoldersAsync(Boolean)
Async/await version of DownloadFolders(Boolean).
Public methodDownloadFoldersAsync(FolderId, Boolean, Boolean)
Public methodDownloadFoldersAsync(FolderId, FolderView, SearchFilter, Boolean)
Public methodDownloadItem(FolderId, Int32)
Downloads an item in the specified folder at the specified index.
Public methodDownloadItem(ItemId, EwsItemParts)
Downloads the specified portions of the specified item by its ID.
Public methodDownloadItem(ItemId, PropertySet)
Downloads the specified item by its ID using PropertySet settings.
Public methodDownloadItem(FolderId, Int32, EwsItemParts)
Downloads the specified portions of an Exchange item in the specified folder at the specified index.
Public methodDownloadItem(FolderId, Int32, PropertySet)
Downloads an item in the specified folder at the specified index using PropertySet settings.
Public methodDownloadItemAsync(FolderId, Int32)
Async/await version of DownloadItem(FolderId, Int32).
Public methodDownloadItemAsync(ItemId, EwsItemParts)
Async/await version of DownloadItem(ItemId, EwsItemParts).
Public methodDownloadItemAsync(ItemId, PropertySet)
Async/await version of DownloadItem(ItemId, PropertySet).
Public methodDownloadItemAsync(FolderId, Int32, EwsItemParts)
Public methodDownloadItemAsync(FolderId, Int32, PropertySet)
Public methodDownloadItemIds(FolderId, Boolean)
Downloads IDs of all or unread items in the specified folder.
Public methodDownloadItemIds(FolderId, ItemView, Boolean)
Downloads IDs of items in the specified folder in the specified ItemView range.
Public methodDownloadItemIdsAsync(FolderId, Boolean)
Async/await version of DownloadItemIds(FolderId, Boolean).
Public methodDownloadItemIdsAsync(FolderId, ItemView, Boolean)
Public methodDownloadItems(FolderId, Boolean)
Downloads all or unread items in the specified folder.
Public methodDownloadItems(IEnumerableEwsItem, EwsItemParts)
Downloads the specified portions of the specified items.
Public methodDownloadItems(IEnumerableEwsItem, PropertySet)
Downloads the specified items using PropertySet settings.
Public methodDownloadItems(FolderId, ItemView, Boolean)
Downloads items in the specified folder in the specified ItemView range.
Public methodDownloadItems(FolderId, ItemView, Boolean, EwsItemParts)
Downloads the specified portions of the items in the specified ItemView range in the specified folder.
Public methodDownloadItems(FolderId, ItemView, Boolean, PropertySet)
Downloads items in the specified folder in the specified ItemView range using PropertySet settings.
Public methodDownloadItems(FolderId, Int32, Int32, Boolean)
Downloads items in the specified folder in the specified range.
Public methodDownloadItems(FolderId, Int32, Int32, Boolean, EwsItemParts)
Downloads the specified portions of Exchange items in the specified folder in the specified range.
Public methodDownloadItems(FolderId, Int32, Int32, Boolean, PropertySet)
Downloads items in the specified folder in the specified range using PropertySet settings.
Public methodDownloadItemsAsync(FolderId, Boolean)
Async/await version of DownloadItems(FolderId, Boolean).
Public methodDownloadItemsAsync(IEnumerableEwsItem, EwsItemParts)
Public methodDownloadItemsAsync(IEnumerableEwsItem, PropertySet)
Public methodDownloadItemsAsync(FolderId, ItemView, Boolean)
Public methodDownloadItemsAsync(FolderId, ItemView, Boolean, EwsItemParts)
Public methodDownloadItemsAsync(FolderId, ItemView, Boolean, PropertySet)
Public methodDownloadItemsAsync(FolderId, Int32, Int32, Boolean)
Public methodDownloadItemsAsync(FolderId, Int32, Int32, Boolean, EwsItemParts)
Public methodDownloadItemsAsync(FolderId, Int32, Int32, Boolean, PropertySet)
Public methodDownloadNativeAttachments
Downloads attachments with the specified string IDs.
Public methodDownloadNativeAttachmentsAsync
Public methodEmptyFolder
Empties a folder with the specified ID.
Public methodEmptyFolderAsync
Async/await version of EmptyFolder(FolderId, Boolean).
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Public methodStatic memberEwsItemsToItemIds
Creates the list of ItemId objects from the collection of EwsItem objects.
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodFindFolderIdByFullName(String)
Gets the ID of the folder denoted by its full name in the MS Exchange account.
Public methodFindFolderIdByFullName(FolderId, String)
Gets the ID of the given folder in the specified containing folder in the MS Exchange account.
Public methodFindFolderIdByFullName(String, Int32)
Gets the ID of the given folder in the MS Exchange account.
Public methodFindFolderIdByFullNameAsync(String)
Async/await version of FindFolderIdByFullName(String).
Public methodFindFolderIdByFullNameAsync(FolderId, String)
Public methodFindFolderIdByFullNameAsync(String, Int32)
Async/await version of FindFolderIdByFullName(String, Int32).
Public methodFindFolderIdByShortName
Gets the ID of the given folder in the MS Exchange account.
Public methodFindFolderIdByShortNameAsync
Public methodFolderExists(String)
Checks if the folder with the specified full name exists in the MS Exchange account.
Public methodFolderExists(FolderId, String)
Checks if the given folder in the specified containing folder exists in the MS Exchange account.
Public methodFolderExistsAsync(String)
Async/await version of FolderExists(String).
Public methodFolderExistsAsync(FolderId, String)
Async/await version of FolderExists(FolderId, String).
Public methodGetErrorDescription
Returns a textual description of the last occurred error.
Public methodGetExchangeVersionString
Gets the MS Exchange version as a string.
Public methodGetFolderByName
Finds the EwsFolder in the given list by the folder's full name.
Public methodGetFolderView
Gets FolderView instance tuned for listing all the folders in the account.
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodInitEwsClient
Sets the default MS Exchange version.
Public methodInitEwsClient(ExchangeVersion)
Sets the specific MS Exchange version.
Public methodInitEwsClient(ExchangeVersion, TimeZoneInfo)
Sets the specific MS Exchange version.
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodMoveFolder
Moves a folder into another folder.
Public methodMoveFolderAsync
Async/await version of MoveFolder(FolderId, FolderId).
Public methodMoveItem
Moves the specified item (e.g. mail message) into the specified folder.
Public methodMoveItemAsync
Async/await version of MoveItem(ItemId, FolderId).
Protected methodOnErrorOccurred
Used by MailBee to raise ErrorOccurred event.
Protected methodOnLogNewEntry
Used by MailBee to raise LogNewEntry event.
Public methodRenameFolder
Renames a folder in the MS Exchange account.
Public methodRenameFolderAsync
Async/await version of RenameFolder(String, FolderId).
Public methodRenameOrMoveFolder
Renames or moves a folder denoted by its full name rather than by ID.
Public methodRenameOrMoveFolderAsync
Public methodResolveName
Resolves the specified name into e-mail addresses which exist on the given MS Exchange server.
Public methodResolveNameAsync
Async/await version of ResolveName(String).
Public methodSearch(FolderId, SearchFilter)
Searches the specified folder for items matching the given criteria.
Public methodSearch(FolderId, SearchFilter, ItemView)
Searches the specified folder for items matching the given criteria and delivers the results accordingly the specified ItemView.
Public methodSearchAsync(FolderId, SearchFilter)
Async/await version of Search(FolderId, SearchFilter).
Public methodSearchAsync(FolderId, SearchFilter, ItemView)
Public methodSendMessage
Sends MailBee mail message.
Public methodSendMessageAndSaveCopy
Sends MailBee mail message and saves a copy in Sent Items or user-defined folder.
Public methodSendMessageAndSaveCopyAsync
Public methodSendMessageAsync
Async/await version of SendMessage(MailMessage).
Public methodSetCredentials(ExchangeCredentials)
Sets the credentials (e.g. OAuth2) of the MS Exchange account for subsequent operations.
Public methodSetCredentials(String, String)
Sets the login and password of the MS Exchange account for subsequent operations.
Public methodSetServerUrl
Gets or sets the URL of EWS service on MS Exchange server.
Public methodTestConnection
Makes a test connection to validate the current settings.
Public methodTestConnectionAsync
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodUpdateItem
Writes the changes made to the item to the MS Exchange server.
Public methodUpdateItemAsync
Async/await version of UpdateItem(EwsItem).
Public methodUploadMessage(FolderId, MailMessage, Boolean)
Uploads MailBee's MailMessage into the specified folder on the MS Exchange server.
Public methodUploadMessage(FolderId, Byte, Boolean)
Uploads raw message data into the specified folder on the MS Exchange server.
Public methodUploadMessageAsync(FolderId, MailMessage, Boolean)
Public methodUploadMessageAsync(FolderId, Byte, Boolean)
Top
Properties
  NameDescription
Public propertyCalculateFolderSizeOnDownload
Gets or sets if folder download operation must also calculate the folder size in bytes.
Public propertyDefaultFolderClass
Gets or sets the default class string to assign to folders being created.
Public propertyDeleteMethod
Gets or sets the mode of deleting items in EWS.
Public propertyStatic memberEnableCompatibilityMode
Gets or sets if MailBee should work around bugs of Microsoft.Exchange.WebServices.dll library.
Public propertyStatic memberEnableSslCertValidation
Gets or sets if SSL certificate of the server must be validated (in case of HTTPS connection).
Public propertyFolderLevelDelimiter
Gets or sets which character to use when delimiting nested folder names.
Public propertyLastResult
Gets a numeric code of the last error.
Public propertyCode exampleLog
Gets the object used for logging MailBee activities into a file or memory buffer.
Public propertyMessageFoldersFilter
Gets SearchFilter instance for reducing the list of the downloaded folders to mail-specific folders.
Public propertyRequireHttps
Gets or sets if only HTTPS end points are allowed by auto-discover procedure.
Public propertyRootFolderType
Gets or sets the top of folder hierarchy in an MS Exchange account.
Public propertyService
Gets a reference to the underlying ExchangeService object.
Public propertySite
Gets or sets the object to be used as a site for the component.
Public propertyThrowExceptions
Gets or sets whether the component will throw exceptions on errors.
Public propertyTrialDaysLeft
Gets the number of days left to the date of the trial license key expiration.
Public propertyVersion
Gets the version of the MailBee assembly.
Top
Events
  NameDescription
Public eventDisposed
Occurs after the component was disposed.
Public eventErrorOccurred
Occurs when the MailBeeException is thrown.
Public eventLogNewEntry
Occurs when an entry is written into the log file (or into the memory buffer if Ews.Log.MemoryLog is true).
Top
Remarks

This class is a wrapper for a subset of EWS Managed API library functions. This wrapper lets the developer work with EWS items in the way typical for other MailBee components (for instance, native exceptions of EWS Managed API are wrapped with MailBeeException, logging with Log property, etc). However, Ews class still exposes native EWS Managed API objects and types so you can utilize EWS Managed API for advanced tasks not directly covered by MailBee.

Note Note
In .NET Core, EWS is supported starting from .NET Core 2.0 (async methods only). In UWP, EWS requires Windows 10 Fall Creators Update as Min Target (async methods only). In .NET Framework, EWS is supported starting from .NET Framework v3.5 (sync methods only, not async). See more details in EWS Managed API topic.

To use EWS, you need to add a reference to MailBee.NET.EWS.DLL (MailBee.NET.EWS package if you're using Nuget). In its turn, MailBee.NET.EWS.DLL references Managed EWS API (Microsoft.Exchange.WebServices.dll or Microsoft.Exchange.WebServices.NETStandard.dll in case of .NET Framework or .NET Core/UWP, respectively). The MailBee.NET.EWS package installs the dependent DLLs automatically.

The typical procedure of accessing EWS:

Examples
This sample demonstrates various scenarios of interacting with MS Exchange server. That's what we do there:
  • Connect to the explicitly defined server host or auto-discover the server host from the e-mail address.
  • Send e-mail and save the copy in Sent Items.
  • Download folders (get folder list, message count in each folder and its size in bytes).
  • Search, sort and download messages and their parts in different ways.
  • Display message contents, save, add and delete attachments.
  • Set Unread message flag.
  • Manipulate folders (e.g. create).
Note Note
In .NET Core or UWP, replace sync methods with their async versions.
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using MailBee.EwsMail;
using Microsoft.Exchange.WebServices.Data;

// We need this because MailMessage type exists in both MailBee and Managed EWS.
using MailBeeMailMessage = MailBee.Mime.MailMessage;
using MailBeeAttachment = MailBee.Mime.Attachment;

class Program
{
    // We use this for displaying all strings but IDs.
    static string Shorten(string text, int maxLen)
    {
        if (text == null || text.Length <= maxLen)
        {
            return text;
        }
        else
        {
            return text.Substring(0, maxLen - 2) + "..";
        }
    }

    // Because IDs usually have diff. endings but the same beginning, we'd better leave ending part.
    static string ShortenId(string text)
    {
        int maxLen = 10;
        if (text == null || text.Length <= maxLen)
        {
            return text;
        }
        else
        {
            return ".." + text.Substring((text.Length - maxLen) + 2);
        }
    }

    // Remove CRLFs from strings to make console outputs easier to read.
    static string Flatten(string text)
    {
        if (text == null)
        {
            return null;
        }
        else
        {
            return text.Replace("\r\n", " ").Replace('\n', ' ');
        }
    }

    static void Main(string[] args)
    {
        // If license key is not set in app.config or Registry, set it here.
        MailBee.Global.LicenseKey = "MN1XX-XXXXXXXX-XXXX";

        // Enable self-signed server certificates. Remove this line to connect only to well-established servers with valid certificates.
        Ews.EnableSslCertValidation = false;
        Ews ewsClient = new Ews();

        // Normally, use TimeZoneInfo.Local, or use TimeZoneInfo.Utc if getting "The specified time zone isn't valid" errors.
        ewsClient.InitEwsClient(ExchangeVersion.Exchange2010_SP1, TimeZoneInfo.Utc);
        // ewsClient.InitEwsClient(ExchangeVersion.Exchange2013_SP1, TimeZoneInfo.Utc); // If your Exchange server is newer or Office 365.

        // Log file can be used for debugging. You can also enable .NET Sockets own log by adding System.Net trace listener in app.config file (.NET Framework only).
        ewsClient.Log.Enabled = true;
        ewsClient.Log.Filename = @"C:\Temp\log.txt";
        ewsClient.Log.Clear();

        // Disabled Gzip results in more traffic (that's bad) but makes debugging easier ("network.log" file will contain human-readable data).
        ewsClient.Service.AcceptGzipEncoding = false;

        string email = "user@contoso.com"; // On-premise Exchange account
        // string email = "user@company.onmicrosoft.com"; // Microsoft account

        // Set on-premise Exchange server URL.
        ewsClient.SetServerUrl("http://domain/EWS/Exchange.asmx");
        ewsClient.SetCredentials(email, "secret");

        // Or set Office 365 server URL.
        // ewsClient.SetServerUrl("https://outlook.office365.com/EWS/Exchange.asmx");
        // ewsClient.SetCredentials(email, "secret"); // Login/password auth
        // ewsClient.SetCredentials(oAuth2Creds); // Or OAuth2 creds, obtained separately (oAuth2Creds must be of ExchangeCredentials type)

        // Or use autodiscover (must be configured on the Exchange server, Office 365 server has autodiscover working).
        // ewsClient.Autodiscover(email);
        // ewsClient.RequireHttps = true;
        // ewsClient.SetCredentials(email, "secret");

        // Send a mail message with attachment to myself.
        MailBeeMailMessage msg = new MailBeeMailMessage();
        msg.Subject = "Test from EWS";
        msg.BodyPlainText = "Test at " + DateTime.Now.ToString();
        msg.BodyHtmlText = "<html>Test at " + DateTime.Now.ToString() + "</html>";
        msg.Attachments.Add(@"C:\Temp\file.doc"); // Adjust this path to make it denote an existing file.
        msg.To.AddFromString("User <user@contoso.com>");
        msg.From.AsString = "User <user@contoso.com>";
        msg.SetUniqueMessageID(null);
        ewsClient.SendMessageAndSaveCopy(msg, null); // Also save copy to Sent Items.
        // ewsClient.SendMessage(msg); // Or just send.

        ewsClient.CalculateFolderSizeOnDownload = true;
        List<EwsFolder> folders = ewsClient.DownloadFolders(null, false, true);
        foreach (EwsFolder folder in folders)
        {
            Console.WriteLine(string.Format("Folder: '{0}', total msgs: {1}, unread: {2}, size in bytes: {3}",
                folder.ShortName, folder.TotalCount, folder.UnreadCount, folder.Size));
            Console.WriteLine(folder.FullName);
        }

        // Get Sent Items folder from its well-known ID.
        EwsFolder sentFolder = ewsClient.DownloadFolderById(WellKnownFolderName.SentItems);
        Console.WriteLine(string.Format("You have {0} sent messages(s)", sentFolder.TotalCount));
        EwsItemList sentItems = ewsClient.DownloadItems(sentFolder.Id, null, false, EwsItemParts.GenericItem);
        EwsItem lastSentItem = sentItems.FindLast(i => i.Subject == "Test from EWS");
        if (lastSentItem != null)
        {
            // Demonstrate deleting messages. It's safe to delete this message because it's a test message we just sent.
            ewsClient.DeleteItem(lastSentItem.Id);
            Console.WriteLine("Deleted saved copy of a message we sent above");
        }
        else
        {
            Console.WriteLine("For some reason, there was no saved copy of a message we sent above");
        }

        // Will demonstrate various methods of getting EWS folder ID which then can then be used with many methods and properties.
        FolderId foldId = null;

        // Method 1: Get FolderId from folder name.
        foldId = ewsClient.FindFolderIdByFullName("Inbox");

        // Method 2: Remember the fact we already have folder list downloaded, grab FolderId from there.
        // Note: this method is currently not working due to a bug in EWS Managed API.
        EwsFolder inbox = folders.Find(fold => (fold.Id.FolderName.HasValue && fold.Id.FolderName.Value == WellKnownFolderName.Inbox));
        if (inbox == null)
        {
            // You'll most probably end up here.
            Console.WriteLine("Well-known folders only supported in Exchange 2013 and higher");
            // You'll also need:
            // ewsClient.InitEwsClient(ExchangeVersion.Exchange2013_SP1, TimeZoneInfo.Utc);
            // ewsClient.EnableCompatibilityMode = false;
            // Update Microsoft.Exchange.WebServices.dll (current version v2.2 crashes when Well-known folder status if retrieved).

            // For the time being, fallback to searching by name.
            inbox = folders.Find(fold => (fold.FullName.ToUpper() == "INBOX"));
        }
        if (inbox == null)
        {
            Console.WriteLine("Couldn't find Inbox");
            return;
        }
        else
        {
            foldId = inbox.Id;
        }

        // Method 3: Or simply get it via WellKnownFolderName directly. Easiest method.
        foldId = WellKnownFolderName.Inbox;

        Console.WriteLine("Download unread messages, body/headers");

        // Default view means "return all items in the natural order".
        ItemView unreadView = null;

        // Or, modify the default view so that only 10 newest items are returned, newer first.
        int pageSize = 10;
        int page = 0;

        // We'll display items in pages.
        unreadView = new ItemView(pageSize, 0);
        unreadView.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Descending);
        EwsItemList unreadItems = null;

        // Here we not using DownloadItems which accepts startIndex and count as we don't know in advance how many items we have.
        // Instead, we're relying on MoreAvailable property from EWS to determine if there are more items left.
        Console.WriteLine("Press Esc to skip downloading the next page of messages (if any).");
        Console.WriteLine();
        while (true)
        {
            unreadItems = ewsClient.DownloadItems(foldId, unreadView, false, EwsItemParts.GenericItem | EwsItemParts.MailMessageBody | EwsItemParts.MailMessageRecipients);
            if (unreadView != null)
            {
                Console.WriteLine(string.Format("Downloading up to {0} message(s) starting at offset {1} from total of {2}, {3} message(s) actually downloaded.",
                    pageSize, unreadView.Offset, unreadItems.TotalCount, unreadItems.Count));
            }
            foreach (EwsItem item in unreadItems)
            {
                Console.WriteLine(string.Format("UID: {0} Text: {1} HTML: {2}",
                    ShortenId(item.UniqueId), Flatten(Shorten(item.BodyPlainText, 40)), Flatten(Shorten(item.BodyHtmlText, 40))));
                Console.WriteLine();
            }
            Console.WriteLine();
            if (unreadItems.MoreAvailable)
            {
                if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.Escape)
                {
                    Console.WriteLine("Esc pressed, will skip downloading the remaining pages and proceed to other examples.");
                    break;
                }
                else
                {
                    Console.WriteLine("Will download the next page.");
                }
            }
            else
            {
                Console.WriteLine("The last page is done.");
                break;
            }
            unreadView.Offset = unreadItems.NextPageOffset;
        }

        Console.WriteLine();

        Console.WriteLine("Download unread messages, full messages with attachments");
        unreadItems = ewsClient.DownloadItems(unreadItems, EwsItemParts.MailMessageFull);
        for (int i = 0; i < unreadItems.Count; i++)
        {
            EwsItem item = unreadItems[i];
            Console.WriteLine(string.Format("ID {0} size: {1}, attachments count: {2}, attachments: {3}", Shorten(item.UniqueId, 10), item.Size,
                item.MailBeeMessage.Attachments.Count,
                string.Join(", ", item.MailBeeMessage.Attachments.Cast<MailBeeAttachment>().Select(a => Shorten(a.Filename, 20)))));

            // For last message, do additional processing.
            if (i == unreadItems.Count - 1)
            {
                if (item.MailBeeMessage.Attachments.Count > 0)
                {
                    // Save all attachments using MailBee.
                    item.MailBeeMessage.Attachments.SaveAll(@"C:\Temp", true);

                    // Save a particular attachment using MailBee.
                    item.MailBeeMessage.Attachments[0].SaveToFolder(@"C:\Temp", true);
                }

                if (item.NativeMessage.Attachments.Count > 0)
                {
                    // Demonstrate working with attachments directly via Managed EWS API.
                    Console.WriteLine("  Attachment ID to name:  " +
                        string.Join(", ", item.NativeMessage.Attachments.Select(a => ShortenId(a.Id) + ": " + Shorten(a.Name, 20))));
                    IEnumerable<FileAttachment> fileAttachs = item.NativeMessage.Attachments.OfType<FileAttachment>();
                    if (fileAttachs.Count() > 0)
                    {
                        Console.WriteLine("  File attachment IDs: " + string.Join(", ", fileAttachs.Select(fa => ShortenId(fa.Id))));
                        FileAttachment fileAttach = fileAttachs.First();
                        fileAttach.Load(Path.Combine(@"C:\Temp", fileAttach.Name)); // This will save attachment to disk.
                    }
                }

                // Add attachment to message and then delete it. This is a kind of action you can only do with EWS and not with POP3 or IMAP, for example
                // (you cannot alter existing messages in POP3/IMAP, only mark them with flags).
                Console.WriteLine(string.Format("Attachment count: {0}", item.NativeMessage.Attachments.Count));
                FileAttachment newAttach = ewsClient.AddAttachmentToItem(item.Id, @"C:\Temp\test.txt", "filename.txt");
                item.NativeItem.Load();
                Console.WriteLine(string.Format("Attachment count: {0}", item.NativeMessage.Attachments.Count));
                Console.WriteLine("Will delete attachment just added");
                int countAttachsDeleted = ewsClient.DeleteAttachment(item.Id, newAttach.Id, true, true);
                item.NativeItem.Load();
                Console.WriteLine(string.Format("Attachment ID: {0}, instances deleted: {1}", ShortenId(newAttach.Id), countAttachsDeleted));
                Console.WriteLine(string.Format("Attachment count: {0}", item.NativeMessage.Attachments.Count));

                bool deleteOtherAttachs = false; // Set to true to enable deletion of other attachments. Do this only in test accounts, not in your normal account!
                if (deleteOtherAttachs)
                {
                    Console.WriteLine("Will delete the remaining attachments, if any");
                    ewsClient.DeleteAttachments(item.Id);
                    item.NativeItem.Load();
                    Console.WriteLine(string.Format("Attachment count: {0}", item.NativeMessage.Attachments.Count));
                }
            }

        }
        Console.WriteLine();

        // Update message flags to mark last message in the folder as unread (just to make sure the search for unread messages below will find at least one message).
        if (inbox.TotalCount > 0)
        {
            EwsItem item = ewsClient.DownloadItem(foldId, 0, EwsItemParts.IdOnly);
            item.IsRead = true;
            ewsClient.UpdateItem(item);
        }

        // Clear keyboard buffer to avoid earlier Esc strokes alter the code flow below.
        while (Console.KeyAvailable)
        {
            Console.ReadKey();
        }

        Console.WriteLine("Search for unread messages via using SearchFilter");
        SearchFilter filt = null; // "No filter" means "Search all messages".
        filt = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false); // Modify filter to allow only unread messages.
        unreadItems = ewsClient.Search(foldId, filt);
        string unreadUids = string.Join(", ", unreadItems.Select(it => ShortenId(it.UniqueId)));
        Console.WriteLine("Unread IDs (you can then pass them to DownloadItems): " + unreadUids);
        Console.WriteLine();

        // Simply display all messages in the folder with paging. We know in advance how many items to display so we don't need MoreAvailable and custom ItemView.
        Console.WriteLine("Display all messages in the folder in paged manner");
        Console.WriteLine("Press Esc to skip downloading the next page of messages (if any).");
        Console.WriteLine();
        EwsItemList items = null;
        while (page * pageSize < inbox.TotalCount)
        {
            // You can replace EwsItemParts.GenericItem with EwsItemParts.MailMessageFull to download full messages (with body/attachments) instead of basic info.
            // If you do this replacement, item.MailBeeMessage will no longer be null.
            items = ewsClient.DownloadItems(foldId, page * pageSize, pageSize, true, EwsItemParts.GenericItem);
            foreach (EwsItem item in items)
            {
                if (item.MailBeeMessage == null)
                {
                    Console.WriteLine(string.Format("To: '{0}', From: '{1}', Subject: '{2}', IsRead: {3}, Size: {4}",
                        Shorten(item.To, 20), Shorten(item.From, 20), Shorten(item.Subject, 20), item.IsRead, item.Size));
                }
                else
                {
                    Console.WriteLine(string.Format("To: '{0}', From: '{1}', Subject: '{2}', IsRead: {3}, Size: {4}, MailBeeMessage.Size: {5}",
                        Shorten(item.To, 20), Shorten(item.From, 20), Shorten(item.Subject, 20), item.IsRead, item.Size, item.MailBeeMessage.Size));
                }
            }
            page++;
            Console.WriteLine("------------");
            if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.Escape)
            {
                Console.WriteLine("Esc pressed, will skip downloading the remaining pages and proceed to other examples.");
                break;
            }
        }

        // Demonstrate working with deeply nested folders. EWS Managed API itself can only work with one level, MailBee adds this functionality on top of EWS.
        if (!ewsClient.FolderExists("Inbox/2nd level/3rd level"))
        {
            // Create a deeply nested folder.
            ewsClient.CreateFolder("Inbox/2nd level/3rd level", null);
            Console.WriteLine("Created folder \"Inbox/2nd level/3rd level\"");
        }
    }
}
See Also