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

  1. Select Certificates & secrets > Client secrets > New client secret.
  2. Add a description for your client secret.
  3. Select an expiration for the secret or specify a custom lifetime.
  4. 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