First of all let me explain my environment, which is I have
- Visual Studio 2022
- Microsoft.Graph version 5.56.0.0
- Microsoft.Identity.Client version 4.63.0.0
I am using this code where after line
var mailFolderCollectionPage = await graphClient.Me.MailFolders.GetAsync();
Visual Studio debugger is completely skipping the exiting application.
Here is my C# code – is there anything wrong with this code?
I have got these permissions in Azure
Code:
private static async System.Threading.Tasks.Task ReadMailsFromExchangeServerByusingmsGraph()
{
var graphClient = GetAuthenticatedGraphClient();
// Fetch mail folders asynchronously
var mailFolderCollectionPage = await graphClient.Me.MailFolders.GetAsync();
// Now you can iterate over the MailFolders
foreach (var mailFolder in mailFolderCollectionPage.Value)
{
Console.WriteLine(mailFolder.DisplayName);
}
}
private static GraphServiceClient GetAuthenticatedGraphClient()
{
var tenantId = ConfigurationManager.AppSettings["tenantId"];
// Value from app registration
var clientId = ConfigurationManager.AppSettings["appId"];
var clientSecret = ConfigurationManager.AppSettings["clientSecret"];
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
var scopes = new[] { "https://graph.microsoft.com/.default" };
// using Azure.Identity;
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
return graphClient;
}
8
Note that:
/me
endpoint works only with user interactive flow not withClientSecretCredential
flow.
- Hence either grant application type API permissions and use
ClientSecretCredential
flow. - If you want to call
/me
endpoint then grant delegated API permissions and use any user interactive flow to perform the action.
As you want to get the Mail folders, you need to grant Mail.Read
application type API permission:
And call await graphClient.Users["{user-id}"].MailFolders.GetAsync()
and modify the code:
namespace ReadMailsFromExchange
{
class Program
{
static async Task Main(string[] args)
{
await ReadMailsFromExchangeServerByUsingMSGraph();
}
private static async Task ReadMailsFromExchangeServerByUsingMSGraph()
{
var graphClient = GetAuthenticatedGraphClient();
var mailFolderCollectionPage = await graphClient.Users["UserID"].MailFolders.GetAsync();
foreach (var mailFolder in mailFolderCollectionPage.Value)
{
Console.WriteLine(mailFolder.DisplayName);
}
}
private static GraphServiceClient GetAuthenticatedGraphClient()
{
var tenantId = "TenantID";
var clientId = "ClientID";
var clientSecret = "ClientSecret";
var scopes = new[] { "https://graph.microsoft.com/.default" };
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
return graphClient;
}
}
}
Recognized by Microsoft Azure Collective