Rebex Graph

.NET client library for MS Graph API (Exchange Online)

Download 30-day free trial Buy from $199
More .NET libraries

Back to feature list...

Message operations

The sample code on this page assumes you have already connected and authenticated to Microsoft 365 (Exchange Online) server.

Getting list of messages 

To get a list of messages, use GetMessageList() method. The following code shows how to get the top page of messages in the Inbox folder.

// create Graph client instance, connect, log in
// ...

// get top page of messages from 'Inbox'
GraphMessageCollection messages = client.GetMessageList(GraphFolderId.Inbox);

// print info about them
foreach (GraphMessageInfo info in messages)
{
    Console.WriteLine("From: {0}", info.From);
    Console.WriteLine("To: {0}", info.To);
    Console.WriteLine("Subject: {0}", info.Subject);
}
Tip: You can make things faster by choosing which message fields to return. By default, server-specific set of properties is returned.

Getting list of messages with paging 

A folder can contain thousands of items. Retrieving all of them might consume a lot of bandwidth and take a very long time. Additionally, it's usually not even possible because Exchange server limits the maximum number of items it can return in response to a single API call.

For many applications, working with several hundreds of latest items is entirely sufficient. When it isn't, use GraphPageView.

The following code shows how to retrieve a list of all messages in the 'Inbox' folder by calling GetMessageList() multiple times using the paging functionality:

// create Graph client instance, connect, log in
// ...

// list all messages in 'Inbox' using paging functionality
int offset = 0;
int pageSize = 1000;
while (true)
{
    // get next page
    GraphMessageCollection messages = client.GetMessageList(
        GraphFolderId.Inbox,
        new GraphPageView(offset, pageSize));

    // print info about messages
    foreach (GraphMessageInfo m in messages)
    {
        Console.WriteLine("[{0}] ({1}) {2}", m.ReceivedDate, m.From, m.Subject);
    }

    // break if there are no more messages
    if (messages.Count == 0)
        break;

    // set next offset
    offset += messages.Count;
}

// final offset corresponds to total number of messages listed
Console.WriteLine("Total messages: {0}", offset);

Getting message info 

To get information about a message, use GetMessageInfo() method.

By default, information specified by GraphMessageFields.Default is retrieved, which includes the default set of properties as returned by Microsoft 365 (Exchange Online) server.

// create Graph client instance, connect, log in
// ...

// construct message ID
GraphMessageId id = new GraphMessageId(messageIdString);

// retrieve envelope of the message
GraphMessageInfo message = client.GetMessageInfo(id, GraphMessageFields.Envelope);

// print some info about the message
Console.WriteLine("Subject: {0}", message.Subject);
Console.WriteLine("From: {0}", message.From);
Console.WriteLine("To: {0}", message.To);

Tip: Limiting the fields to those you need to retrieve might improve the performance of your application.

Downloading messages 

To download and parse a whole mail message into a MailMessage object, use GetMailMessage() method:

// create Graph client instance, connect, log in
// ...

// get a message
MailMessage message = client.GetMailMessage(messageId);

// print some info about the message
Console.WriteLine("Subject: {0}", message.Subject);
Console.WriteLine("From: {0}", message.From);
Console.WriteLine("To: {0}", message.To);
foreach (Attachment item in message.Attachments)
{
    Console.WriteLine(" * {0} <{1}>", item.DisplayName, item.ContentType);
}

This retrieves an instance of high-level MailMessage object. If you prefer the low-level API (MimeMessage object), call GetMimeMessage() method instead.

Alternatively, you can download a message into a file using GetMessage() method:

// create Graph client instance, connect, log in
// ...

// download a message to a file in MIME format
client.GetMessage(messageId, @"C:\data\message.eml");

To download a message into a Stream, use another GetMessage() overload:

// create Graph client instance, connect, log in
// ...

using (Stream writer = File.Create(@"C:\data\message.eml"))
{
    // download a message to a stream in MIME format
    client.GetMessage(messageId, writer);
}

Uploading messages 

You can also upload messages to a folder at the server without sending them. The StoreMessage() method accepts MailMessage or MimeMessage object. To upload a mail message from a file or stream, load it to MailMessage or MimeMessage object first:

// create Graph client instance, connect, log in
// ...

// load a mail message
MailMessage mail = new MailMessage();
mail.Load(@"C:\data\message.eml");

// upload the mail to 'Drafts' folder
GraphMessageInfo message = client.StoreMessage(GraphFolderId.Drafts, mail);

// keep its ID for later use if needed
var messageId = message.Id;

Moving messages 

To move a message to another folder, use MoveMessage() method.

// create Graph client instance, connect, log in
// ...

DateTime yesterday = DateTime.Today.AddDays(-1);

// find top page of messages that arrived to 'Inbox' yesterday
var items = client.Search(GraphFolderId.Inbox,
                          GraphMessageSearchParameter.Arrived(yesterday));

// move all of them to 'Archive' folder
foreach (GraphMessageInfo item in items)
{
    client.MoveMessage(item.Id, GraphFolderId.Archive);
}

Tip: The MoveMessage() method returns info about the new item, including its new ID.

Deleting messages 

To delete a message, use DeleteMessage() method.

// create Graph client instance, connect, log in
// ...

// delete desired message
client.DeleteMessage(messageId);

Searching for messages 

Use Search() method to search for messages matching the specified criteria. Check out Searching section for more information.

Exchange and MIME IDs 

Exchange Online (Microsoft 365) server distinguishes various types of items. In Rebex Graph, these are represented by different classes. Currently supported are:

  • Folder: GraphFolderId - represents mailbox folders and subfolders (such as 'Inbox', 'Sent Items' or 'Drafts').
  • Message: GraphMessageId - represents e-mail messages.

These IDs are available as Id property of GraphFolderInfo and GraphMessageInfo classes. There are also several pre-defined folder IDs that can be used to access well-known folders.

Note: GraphMessageInfo and MailMessage classes also feature the MessageId property. This represents the Message-ID MIME header that is not related to Exchange IDs.

To convert an Exchange ID to a MIME Message-ID, retrieve the message envelope info:

// get Envelope info of a message with desired Exchange ID (graphMessageId)
var message = client.GetMessageInfo(graphMessageId, GraphMessageFields.Envelope);

// read Message-ID (MIME header) from the message info
var mimeMessageId = message.MessageId;

To Convert a MIME Message-ID to an Exchange ID, use the Search method:

// search for messages with desired Message-ID MIME header
// the header is represented by 'internetMessageId' in Microsoft Graph API
// specify null folder to search anywhere in the mailbox
var messages = client.Search(folderId: null, new GraphMessageSearchQuery()
{
    Fields = GraphMessageFields.Id,
    RawFilter = $"internetMessageId eq '{mimeMessageId}'"
});

Console.WriteLine("Messages with Message-ID '{0}':", mimeMessageId);
foreach (GraphMessageInfo info in messages)
{
    Console.WriteLine(info.Id);
}

Note: Exchange Online (Microsoft 365) IDs are case-sensitive strings, which makes them unsuitable to be used as a file name on case-insensitive file systems.

Message fields 

Many GraphClient methods make it possible to specify which message information to retrieve. These methods include GetMessageInfo(), GetMessageList(), Search(). It's recommended to only request the information you need - this can save a lot of time, bandwidth and processing power.

Use the GraphMessageFields argument to specify which information to retrieve:

Parameter value Description
GraphMessageFields.Default Default set of fields defined by Exchange Online (Microsoft 365) server. This is the default for methods with optional fields argument.
GraphMessageFields.Id Only retrieves the Exchange message ID.
GraphMessageFields.Subject Retrieves message subject.
GraphMessageFields.Body Retrieves message body (HTML if available, plain text otherwise).
GraphMessageFields.AttachmentInfo Retrieves information about attachments.
GraphMessageFields.Envelope Retrieves message ID and envelope info. This includes the most important fields such as Date, From, To, Subject, and Message-ID.
GraphMessageFields.Info Retrieves message ID, envelope info, attachment info and additional fields such as Importance, Flag, Categories, IsRead, and LastModifiedDate.

Note: These fields are bit flags, which means that combinations such as Envelope | Body are possible - use bitwise OR operator (| in C#, Or in VB.NET).

The following code shows how to combine multiple GraphMessageFields to get desired results:

// create Graph client instance, connect, log in
// ...

// get message envelope and attachment info
GraphMessageInfo message = client.GetMessageInfo(messageId,
    GraphMessageFields.Envelope | GraphMessageFields.AttachmentInfo);

// print some info about the message
Console.WriteLine("Subject: {0}", message.Subject);
Console.WriteLine("From: {0}", message.From);
Console.WriteLine("To: {0}", message.To);
if (message.HasAttachments)
{
    Console.WriteLine("Message has attachment(s).");
}

Back to feature list...