Send email via Office 365 Account
Posted on: 1/7/2025 10:20:00 AM
Sending emails through SMTP with your Office 365/Outlook account is now outdated, as Microsoft no longer supports this method. After spending hours troubleshooting SMTP issues, I discovered a straightforward and modern solution: using the Microsoft Graph API.
First, Create App and set Permisson.
1. Sign in to the Microsoft Entra admin center
2. Browse to Identity > Applications > App registrations and select New registration
3. Input some require field and choose Supported account types
4. Click Register button

➡️ Copy:
- Application (Client ID)
- Directory (Tenant ID)

Second, add credentials
- Select Certificates & secrets > Client secrets > New client secret.
- Add a description for your client secret.
- Select an expiration for the secret or specify a custom lifetime.
- Click Add

➡️ Copy Secret Value (This secret value is never displayed again after you leave this page)
Grant API permissions

Back to our application
Add settings as bellow to your appSettings.json:
//other config ...
"AzureAd": {
"ClientId": "your client id from step 1",
"TenantId": "your tenant id from step 1",
"ClientSecret": "your client secret value from step 2",
"Mail": "noreply@yourdomain.com"
}
In Program.cs
builder.Services.AddOptions();
var azureAdsettings = builder.Configuration.GetSection("AzureAd");
builder.Services.Configure<AzureAdSettings>(azureAdsettings);
MailService.cs
//dependencies
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Azure.Identity;
private GraphServiceClient GetGraphServiceClient()
{
// Create the TokenCredential
var credential = new ClientSecretCredential(
_azureAdSettings.TenantId,
_azureAdSettings.ClientId,
_azureAdSettings.ClientSecret
);
// Create the GraphServiceClient
return new GraphServiceClient(credential);
}
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
try
{
var graphClient = GetGraphServiceClient();
var mailTemplate = System.IO.File.ReadAllText(Path.Combine(_webHostEnvironment.ContentRootPath, "MailTemplate", "Default.html"));
var bodyHtml = mailTemplate.Replace("{{BODY}}", htmlMessage);
var message = new Message
{
Subject = subject,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = bodyHtml
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = email
}
}
}
};
Microsoft.Graph.Users.Item.SendMail.SendMailPostRequestBody body = new()
{
Message = message,
SaveToSentItems = false
};
await graphClient.Users[_azureAdSettings.Mail].SendMail.PostAsync(body);
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
Then you can use like this
SendEmailAsync("demo-email@some-domain.com", "Your OTP code", $"Your OTP Code is: {code}");
References
- Register an application with the Microsoft identity platform: https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=certificate
- Microsoft Graph permissions and scopes: https://learn.microsoft.com/vi-vn/microsoftteams/platform/bots/how-to/authentication/bot-sso-graph-api
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.