Folder sync gets your folders from the graph api. Sometimes folders have child folders within them and it is important to fetch them too. For this example, we are going to go down to one level deep and save the results in a json file for easy investigation of the data received.
A local message model that is separate representation of the models provided by the client library.
See the actual folder object here: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/mailfolder
Property | Function |
---|---|
Id | The Id of the folder |
Name | The name of the folder |
ParentId | Id of the folder parent folder if it is a child folder |
MessageItems | list of messages in the folder |
SkipToken | Optional nullable property that is updated during pagination to store the skip token |
StartupFolder | boolean property that makes the inbox folder and its child folders visible first |
This results in a call to get the signed in user's mailfolder.
Request: GET graph.microsoft.com/v1.0/me/mailfolders
You would need to pass an instance of the authenticated graph client
var folders = await graphClient.Me.MailFolders.Request().GetAsync();
After receiving the list of folders, you should loop through them to get the list of child folders using the folder Id. We've added a few dashes at the front of the name to show child folders.
Request: GET graph.microsoft.com/v1.0/me/mailfolders/{id}/childFolders
The graph request looks like this
var childFolders = await graphClient.Me.MailFolders[folder.Id].ChildFolders.Request().GetAsync();
Here is an example of how to fetch the folders and the child folders.
Add these to your MailService.cs
class.
public async Task<List<FolderItem>> GetMyMailFolders(GraphServiceClient graphClient)
{
List<FolderItem> items = new List<FolderItem>();
var folders = await graphClient.Me.MailFolders.Request().GetAsync();
if (folders?.Count > 0)
{
foreach (var folder in folders)
{
// checks if it is the mailbox folder so that when displayed,
// it can show up first in the list
var isStartUpFolder = (folder.DisplayName == "Inbox");
var folderMessages = await GetMyFolderMessages(graphClient, folder.Id, null);
items.Add(new FolderItem
{
Name = folder.DisplayName,
Id = folder.Id,
ParentId = null,
StartupFolder = isStartUpFolder
});
var clientFolders = await GetChildFolders(graphClient, folder.Id, isStartUpFolder);
items.AddRange(clientFolders);
}
}
return items;
}
private async Task<List<FolderItem>> GetChildFolders(GraphServiceClient graphClient, string id, bool isStartUpFolder)
{
List<FolderItem> children = new List<FolderItem>();
var childFolders = await graphClient.Me.MailFolders[id].ChildFolders.Request().GetAsync();
if (childFolders?.Count > 0)
{
foreach (var child in childFolders)
{
var folderMessages = await GetMyFolderMessages(graphClient, child.Id, null);
children.Add(new FolderItem
{
Name = "-- " + child.DisplayName,
Id = child.Id,
ParentId = child.ParentFolderId,
StartupFolder = isStartUpFolder
});
}
}
return children;
}
You can learn more about these requests on List mailFolders and List child folders
Create an action in HomeController.cs
called GetMyMailfolders.
This should pass the results of fetching the folders from the graph API to the data service for storage of the details.
public async Task<ActionResult> GetMyMailfolders()
{
var results = new FoldersViewModel();
try
{
// Get the folders.
var folderResults = await mailService.GetMyMailFolders(graphClient);
foreach (var folder in folderResults)
{
dataService.StoreFolder(folder);
}
}
catch (ServiceException se)
{
if (se.Error.Code == "AuthenticationFailure")
{
return new EmptyResult();
}
// Personal accounts that aren't enabled for the Outlook REST API get a "MailboxNotEnabledForRESTAPI" or "MailboxNotSupportedForRESTAPI" error.
return RedirectToAction("Index", "Error", new { message = string.Format("Error in {0}: {1} {2}", Request.RawUrl, se.Error.Code, se.Error.Message) });
}
return RedirectToAction("Index");
}
After its successful completion, it will redirect you to the Index
action.
The index action fetches the stored folders from the storage using the DataService's GetFolders method.
The action goes through the items stored in the json file, creates a list of folder items and passes it to the UI.
public ActionResult Index()
{
var folderResults = new FoldersViewModel();
var folders = dataService.GetFolders();
var resultItems = new List<FolderItem>();
folderResults.Items.ToList().AddRange(folders);
folderResults.Items = resultItems;
return View("Index", folderResults);
}