I'm trying to make some modifications to the DotNetCoreRazor_MSGraph sample project so that instead of just presenting mails, regardless of folder, it first creates the folder structure.
This is the code for EmailFolders.cshtml:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetCoreRazor_MSGraph.Graph;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.Graph;
using Microsoft.Identity.Web;
using Newtonsoft.Json;
namespace DotNetCoreRazor_MSGraph.Pages
{
[AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
public class EmailFoldersModel : PageModel
{
private readonly GraphEmailClient _graphEmailClient;
private readonly GraphServiceClient _graphServiceClient;
private string inboxid = null;
private string sentitemsid = null;
private string draftsid = null;
[BindProperty(SupportsGet = true)]
public string NextLink { get; set; }
public IEnumerable<Message> Messages { get; private set; }
public EmailFoldersModel(GraphEmailClient graphEmailClient, GraphServiceClient graphServiceClient)
{
_graphEmailClient = graphEmailClient;
_graphServiceClient = graphServiceClient;
}
public StringBuilder sb = new StringBuilder();
public List<MailFolder> folders = new List<MailFolder>();
public async Task OnGetAsync()
{
MailFolder inbox = await _graphServiceClient.Me.MailFolders.Inbox.Request().GetAsync();
inboxid = inbox.Id;
MailFolder sentitems = await _graphServiceClient.Me.MailFolders.SentItems.Request().GetAsync();
sentitemsid = sentitems.Id;
MailFolder drafts = await _graphServiceClient.Me.MailFolders.Drafts.Request().GetAsync();
draftsid = drafts.Id;
//get all folders on all pages
IUserMailFoldersCollectionPage flds = await _graphServiceClient.Me.MailFolders.Request().GetAsync();
folders.AddRange(flds.CurrentPage);
while (flds.NextPageRequest != null)
{
flds = await flds.NextPageRequest.GetAsync();
folders.AddRange(flds.CurrentPage);
}
//move drafts to the top of the list
foreach (MailFolder folder in folders)
{
if (folder.Id == draftsid)
{
folders.Remove(folder);
folders.Prepend(folder);
break;
}
}
//move sentitems to the top of the list
foreach (MailFolder folder in folders)
{
if (folder.Id == sentitemsid)
{
folders.Remove(folder);
folders.Prepend(folder);
break;
}
}
//move inbox to the top of the list
foreach (MailFolder folder in folders)
{
if (folder.Id == inboxid)
{
folders.Remove(folder);
folders.Prepend(folder);
break;
}
}
//create the HTML <ul> structure
sb.AppendLine("<ul id=\"myUL\">");
foreach (MailFolder folder in folders.Where(f => f.ParentFolderId == null))
{
if (folder.ChildFolderCount > 0)
sb.AppendLine("<li class=\"caret\">");
else
sb.AppendLine("<li>");
sb.AppendLine(folder.DisplayName);
if (folder.ChildFolderCount > 0)
{
await CreateList(folder.Id);
}
sb.AppendLine("</li>");
}
sb.AppendLine("</ul>");
await Task.CompletedTask;
}
//html recursor
private async Task CreateList(string MailFolderId)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("<ul class=\"nested\">");
foreach (MailFolder folder in folders.Where(f => f.ParentFolderId == MailFolderId))
{
if (folder.ChildFolderCount > 0)
sb.AppendLine("<li class=\"caret\">");
else
sb.AppendLine("<li>");
sb.AppendLine(folder.DisplayName);
if (folder.ChildFolderCount > 0)
{
await CreateList(folder.Id);
}
sb.AppendLine("</li>");
}
sb.AppendLine("</ul>");
}
//folder recursor
private async Task GetChildFolders(string MailFolderId)
{
List<MailFolder> childfolders = new List<MailFolder>();
IMailFolderChildFoldersCollectionPage chlds = await _graphServiceClient.Me.MailFolders[MailFolderId].ChildFolders.Request().GetAsync();
childfolders.AddRange(chlds.CurrentPage);
while (chlds.NextPageRequest != null)
{
chlds = await chlds.NextPageRequest.GetAsync();
childfolders.AddRange(chlds.CurrentPage);
}
folders.AddRange(childfolders);
foreach (MailFolder folder in childfolders)
{
if (folder.ChildFolders.Count > 0)
{
await GetChildFolders(folder.Id);
}
}
}
}
}
On the EmailFolders.cshtml page, I'm trying to grab the folder structure with @Html.Raw(Model.sb.ToString()). I know OnGetAsync is being called, because the result is <ul id="myUL"></ul> (with carriage returns after each tag). But I'm trying to see why nothing is being added to the folders list, and it's bypassing any breakpoints I use. Breakpoints on EmailFolders.cshtml work, but that doesn't help, because it's after the codebehind is finished.
ParentFolderIdto find other folders at the same level e.g:var rootParentFolderId = inbox.ParentFolderId;Then, instead of checking fornull, use:foreach (MailFolder folder in folders.Where(f => f.ParentFolderId == rootParentFolderId)) { AppendFolderHtml(folder); }Console.WriteLine("Retrieving all folders..."); IUserMailFoldersCollectionPage flds = await _graphServiceClient.Me.MailFolders.Request().GetAsync(); if (flds.CurrentPage.Count == 0) { Console.WriteLine("No folders retrieved."); } else { Console.WriteLine($"{flds.CurrentPage.Count} folders retrieved."); }