Adding Email - Code

C#

EmailTestPage.razor

@page "/emailtest/"

@using MailKit.Net.Smtp;
@using MailKit.Security;
@using MimeKit;
@using MimeKit.Text;

@inject IEmailService EmailService

<h3>Email Test Page</h3>

<hr />
<br/>
<div>
    <p class="alert-success">
        These are the settings for common email providers.  Substitute in the code as necessary.
         <br/>
    </p>
    <p>
        //GMail<br />
        smtp.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
        <br/>
    </p>
    <p>
        //Outlook<br />
        smtp.Connect("smtp-mail.outlook.com", 587, SecureSocketOptions.StartTls);
        <br/>
    </p>
    <p>
        //Office 365<br />
        smtp.Connect("smtp.office365.com", 587, SecureSocketOptions.StartTls);
        <br/>
    </p>
    <p>
        //Generic<br />
        smtp.Connect("smtp.ServerNameOrDomainName", 587, SecureSocketOptions.StartTls);<br />
        or:<br />
        smtp.Connect("mail.ServerNameOrDomainName", 587, SecureSocketOptions.StartTls);
        <br/>
    </p>
</div>
<br/>
<hr />
<br/>
<div class="button-container">
    <button type="button" class="e-btn e-normal e-primary" @onclick="@SendEmail">Send Email</button>
</div>

@code {
    public MimeMessage email = new MimeMessage();

    public void SendEmail()
    {
        //email.From.Add(MailboxAddress.Parse("FromEmailAddress"));
        //email.To.Add(MailboxAddress.Parse("ToEmailAddress"));
        //email.Subject = "Email Subject goes here";
        //email.Body = new TextPart(TextFormat.Html) { Text = "This is the body of the email" };

        //// send email
        //using var smtp = new SmtpClient();        
        //smtp.Connect("smtp-mail.outlook.com", 587, SecureSocketOptions.StartTls);
        //smtp.Authenticate("FromUserName", "FromUserPassword");
        //smtp.Send(email);
        //smtp.Disconnect(true);

        if (EmailService.Send("FromEmailAddress", "Email Subject goes here", "This is the body of the email"))
        {
            //do something
        }
        else
        {
            //do something else
        };

    }
}

_Imports.razor

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop

@using BlazorBirthdayReminders
@using BlazorBirthdayReminders.Shared

@using Syncfusion.Blazor
@using Syncfusion.Blazor.Inputs  
@using Syncfusion.Blazor.Popups
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Calendars
@using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Lists
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.Notifications

@using BlazorBirthdayReminders.Data

EmailSender.cs

using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.Extensions.Configuration;
using MimeKit;
using MimeKit.Text;
using System;


namespace BlazorBirthdayReminders.Data;

public interface IEmailService
{
    bool Send(string to, string subject, string body);
}

public class EmailService : IEmailService
{
    private readonly IConfiguration configuration;

    public EmailService(IConfiguration Configuration)
    {
        configuration = Configuration;
    }

    public bool Send(string to, string subject, string body)
    {
        //Get settings from appsettings
        var SmtpHost = configuration["SmtpHost"];
        var SmtpPort = configuration["SmtpPort"];
        var SmtpUserFriendlyName = configuration["SmtpUserFriendlyName"];
        var SmtpUserEmailAddress = configuration["SmtpUserEmailAddress"];
        var SmtpPass = configuration["SmtpPass"];
        // create message
        var email = new MimeMessage();
        email.From.Add(new MailboxAddress(SmtpUserFriendlyName, SmtpUserEmailAddress));
        email.To.Add(new MailboxAddress(to, to));
        email.Subject = subject;
        email.Body = new TextPart(TextFormat.Html) { Text = body };

        try
        {
            // send email
            using var smtp = new SmtpClient();

            smtp.Connect(SmtpHost, Int32.Parse(SmtpPort), SecureSocketOptions.StartTls);
            smtp.Authenticate(SmtpUserEmailAddress, SmtpPass);
            smtp.Send(email);
            smtp.Disconnect(true);

            return true;
        }
        catch
        {
            return false;
        }

    }
}
<div class="top-row ps-3 navbar navbar-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="">BlazorBirthdayReminders</a>
        <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
            <span class="navbar-toggler-icon"></span>
        </button>
    </div>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="counter">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="emailtest">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Email Test
            </NavLink>
        </div>
    </nav>
</div>

@code {
    private bool collapseNavMenu = true;

    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
}

appsettings.json

Note that placeholders are shown, and should be replaced by your own credentials (both for Azure B2C and Email).

{
  /*
The following identity settings need to be configured
before the project can be successfully executed.
For more info see https://aka.ms/dotnet-template-ms-identity-platform 
*/
  "AzureAd": {
    "Instance": "https://AzureB2CName.b2clogin.com/tfp/",
    "Domain": "AzureB2CName.onmicrosoft.com",
    "TenantId": "TenantID",
    "ClientId": "ClientID",
    "CallbackPath": "/signin-oidc",
    "SignUpSignInPolicyId": "SignUpSignInPolicyID"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Default": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Birthdays;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
  },
  "SyncfusionLicenceKey": "SyncfusionLicenceKey",
  "SmtpHost": "smtpHostName",
  "SmtpPort": 587,
  "SmtpUserFriendlyName": "Your name here", //E.g John Smith
  "SmtpUserEmailAddress": "SmtpUserEmailAddress",
  "SmtpPass": "EmailPassword"
}

Program.cs

using BlazorBirthdayReminders.Data;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using Syncfusion.Blazor;


var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
    .AddMicrosoftIdentityConsentHandler();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<IPersonService, PersonService>();
builder.Services.AddScoped<IEmailService, EmailService>();

builder.Services.AddSyncfusionBlazor(options => { options.IgnoreScriptIsolation = true; });

var app = builder.Build();

///Register Syncfusion license
var SyncfusionLicenceKey = builder.Configuration["SyncfusionLicenceKey"];
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(SyncfusionLicenceKey);

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();