Sending Emails via SendGrid - Code

C#

These are the files that have been changed in this post.

appsettings.json

{
  "SmtpHost": "smtp.hostname.com",
  "SmtpPort": 587,
  "SmtpUserFriendlyName": "Your name here", //E.g John Smith
  "SmtpUserEmailAddress": "SmtpUserEmailAddress",
  "SmtpPass": "EmailPassword",
  "SENDGRID_APIKEY": "SendGrid apikey",
  "SenderEmail": "SendGrid SenderEmail",
  "SenderEmailFriendlyName": "Your name here", //E.g John Smith
  "ConnectionStrings": {
    "DefaultConnection": "Your PurchaseOrdersAuth database Connection String goes here",
    "SqlDBcontext": "Your PurchaseOrders database Connection String goes here"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

EmailSenderSendGrid.cs

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using SendGrid;
using SendGrid.Helpers.Mail;

namespace BlazorPurchaseOrders.Data
{
    public interface IEmailSender
    {
        Task<bool> SendEmail(string toEmail, string subject, string body);
    }

    public class EmailSender : IEmailSender
    {
        private readonly IConfiguration configuration;

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

        public async Task<bool> SendEmail(string toEmail, string subject, string body)
        {
            var apiKey = configuration["SENDGRID_APIKEY"];
            var client = new SendGridClient(apiKey);
            var FromFriendlyName = configuration["SenderEmailFriendlyName"];
            var FromEmailAddress = configuration["SenderEmail"];
            var from = new EmailAddress(FromEmailAddress, FromFriendlyName);            
            var to = new EmailAddress(toEmail, toEmail);
            var plainTextContent = body;
            var htmlContent = body;
            var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
            var response = await client.SendEmailAsync(msg).ConfigureAwait(false);
            return response.IsSuccessStatusCode;           
        }
    }
}

Startup.cs

using BlazorPurchaseOrders.Areas.Identity;
using BlazorPurchaseOrders.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Syncfusion.Blazor;

namespace BlazorPurchaseOrders
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //Syncfusion support
            services.AddSyncfusionBlazor();
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles <IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
            services.AddDatabaseDeveloperPageExceptionFilter();
            services.AddSingleton<WeatherForecastService>();
            var sqlConnectionConfiguration = new SqlConnectionConfiguration(Configuration.GetConnectionString("SqlDBContext"));
            services.AddSingleton(sqlConnectionConfiguration);
            services.AddScoped<IPOHeaderService, POHeaderService>();
            services.AddScoped<IPOLineService, POLineService>();
            services.AddScoped<IProductService, ProductService>();
            services.AddScoped<ISupplierService, SupplierService>();
            services.AddScoped<ITaxService, TaxService>();
            services.AddScoped<IEmailService, EmailService>();
            services.AddScoped<IEmailSender,EmailSender>();

            //services.AddHttpContextAccessor();  //used for getting logged in user
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //Register Syncfusion license
            Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Your Syncfusion Licence Key");
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseMigrationsEndPoint();
            }
            else
            {
                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.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }

        
    }
}

Index.razor

@page "/"
@using BlazorPurchaseOrders.Data

@inject IPOHeaderService POHeaderService
@inject NavigationManager NavigationManager
@inject IJSRuntime IJS
@inject IEmailService EmailService
@inject IEmailSender EmailSender

@attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous]

@inject AuthenticationStateProvider AuthenticationStateProvider

<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
</head>

<div class="col-sm-12">
    <AuthorizeView>
        <NotAuthorized>
            <h5>Please Log in</h5>
            <h6>or</h6>
            <h5>Register to use Blazor Purchase Orders</h5>
        </NotAuthorized>
        <Authorized>
            <h3>Purchase Orders</h3>
            <br />
            <SfGrid DataSource="@poheader"
                    Toolbar="Toolbaritems">
                <GridEvents RowSelected="RowSelectHandler" OnToolbarClick="ToolbarClickHandler" TValue="POHeader"></GridEvents>
                <GridColumns>
                    <GridColumn Field="@nameof(POHeader.POHeaderOrderNumber)"
                                HeaderText="No"
                                TextAlign="@TextAlign.Left"
                                Width="10">
                    </GridColumn>
                    <GridColumn Field="@nameof(POHeader.POHeaderOrderDate)"
                                HeaderText="Date"
                                Format="d"
                                Type="ColumnType.Date"
                                TextAlign="@TextAlign.Center"
                                Width="15">
                    </GridColumn>
                    <GridColumn Field="@nameof(POHeader.SupplierName)"
                                HeaderText="Supplier"
                                TextAlign="@TextAlign.Left"
                                Width="40">
                    </GridColumn>
                    <GridColumn Field="@nameof(POHeader.TotalOrderValue)"
                                HeaderText="Value"
                                TextAlign="@TextAlign.Right"
                                Format="C2"
                                Width="20">
                    </GridColumn>
                    <GridColumn Field="@nameof(POHeader.POHeaderRequestedBy)"
                                HeaderText="Requested by"
                                TextAlign="@TextAlign.Left"
                                Width="40">
                    </GridColumn>
                </GridColumns>
            </SfGrid>

            <WarningPage @ref="Warning" WarningHeaderMessage="@WarningHeaderMessage" WarningContentMessage="@WarningContentMessage" />

            <ConfirmPage @ref="ConfirmOrderDelete" ConfirmHeaderMessage="@ConfirmHeaderMessage" ConfirmContentMessage="@ConfirmContentMessage" ConfirmationChanged="ConfirmOrderArchive" />

        </Authorized>
    </AuthorizeView>
</div>

<div class="col-lg-12 control-section toast-default-section">
    <SfToast @ref="ToastObj" Timeout="4000">
        <ToastPosition X="Right" Y="Top"></ToastPosition>
    </SfToast>
</div>

<style>
    @@font-face {
        font-family: 'Toast_icons';
        src: url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype');
        font-weight: normal;
        font-style: normal;
    }

    #toast_types button {
        margin: 5px;
        min-width: 160px;
        max-width: 160px;
    }

    .toast-icons {
        font-family: 'Toast_icons' !important;
        speak: none;
        font-size: 55px;
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-transform: none;
        line-height: 1;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
    }

    #toast_type .e-toast-icon.e-icons {
        height: auto;
        font-size: 30px;
    }

    .toast-icons.e-success::before {
        content: "\e701";
    }

    .toast-icons.e-error::before {
        content: "\e700";
    }

    .toast-icons.e-info::before {
        content: "\e704";
    }

    .toast-icons.e-warning::before {
        content: "\e703";
    }

    #toast_types {
        text-align: center;
    }
</style>

@code {

    // Create an empty list, named poheader, of empty POHeader objects.
    IEnumerable<POHeader> poheader;
    POHeader orderHeader = new POHeader();

    private List<ItemModel> Toolbaritems = new List<ItemModel>();

    //int POHeaderID = 0;

    private int selectedPOHeaderID { get; set; } = 0;
    private Guid selectedPOHeaderGuid { get; set; }
    private string selectedPOHeaderSupplierEmail { get; set; } = "";
    private int selectedPOHeaderOrderNumber { get; set; } = 0;

    WarningPage Warning;
    string WarningHeaderMessage = "";
    string WarningContentMessage = "";

    ConfirmPage ConfirmOrderDelete;
    string ConfirmHeaderMessage = "";
    string ConfirmContentMessage = "";
    public bool ConfirmationChanged { get; set; } = false;

    private string emailbody = "";

    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    SfToast ToastObj;

    private List<ToastModel> Toast = new List<ToastModel>
{
    new ToastModel{ Title = "Warning!", Content="There was a problem with your network connection.", CssClass="e-toast-warning", Icon="e-warning toast-icons" },
    new ToastModel{ Title = "Success!", Content="Your message has been sent successfully.", CssClass="e-toast-success", Icon="e-success toast-icons" },
    new ToastModel{ Title = "Error!", Content="A problem has been occurred while submitting your email", CssClass="e-toast-danger", Icon="e-error toast-icons" },
    new ToastModel{ Title = "Information!", Content="Please read the comments carefully.", CssClass="e-toast-info", Icon="e-info toast-icons" }
    };

    protected override async Task OnInitializedAsync()
    {
        //Populate the list of orders objects from the Purchase Order Header table.
        await GetOrderList();

        Toolbaritems.Add(new ItemModel() { Text = "Add", TooltipText = "Add a new order", PrefixIcon = "e-add" });
        Toolbaritems.Add(new ItemModel() { Text = "Edit", TooltipText = "Edit selected order", PrefixIcon = "e-edit" });
        Toolbaritems.Add(new ItemModel() { Text = "Delete", TooltipText = "Delete selected order", PrefixIcon = "e-delete" });
        Toolbaritems.Add(new ItemModel() { Text = "Preview", TooltipText = "Preview selected order", PrefixIcon = "e-print" });
        Toolbaritems.Add(new ItemModel() { Text = "Email", TooltipText = "Email selected order", PrefixIcon = "bi-envelope" });
    }


    public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
    {
        if (args.Item.Text == "Add")
        {
            //Code for adding goes here
            //POHeaderID = 0;
            NavigationManager.NavigateTo($"/purchaseorder/{Guid.Empty}");
        }

        if (args.Item.Text == "Edit")
        {
            //Code for editing - Check that an Order has been selected from the grid
            if (selectedPOHeaderID == 0)
            {
                WarningHeaderMessage = "Warning!";
                WarningContentMessage = "Please select an Order from the grid.";
                Warning.OpenDialog();
            }
            else
            {
                NavigationManager.NavigateTo($"/purchaseorder/{selectedPOHeaderGuid}");
            }
        }

        if (args.Item.Text == "Delete")
        {
            //Code for deleting
            if (selectedPOHeaderID == 0)    //Check that an order has been selected
            {
                WarningHeaderMessage = "Warning!";
                WarningContentMessage = "Please select an Order from the grid.";
                Warning.OpenDialog();
            }
            else
            {
                //Populate orderHeader using selectedPOHeaderID
                orderHeader = await POHeaderService.POHeader_GetOne(selectedPOHeaderID);

                ConfirmHeaderMessage = "Confirm Deletion";
                ConfirmContentMessage = "Please confirm that this order should be deleted.";
                ConfirmOrderDelete.OpenDialog();
            }
        }

        if (args.Item.Text == "Preview")
        {

            //Code for editing - Check that an Order has been selected from the grid
            if (selectedPOHeaderID == 0)
            {
                WarningHeaderMessage = "Warning!";
                WarningContentMessage = "Please select an Order from the grid.";
                Warning.OpenDialog();
            }
            else
            {
                await IJS.InvokeAsync<object>("open", new object[] { "/previeworder/" + selectedPOHeaderGuid + "", "_blank" });
            }
        }

        if (args.Item.Text == "Email")
        {
            //Code for editing - Check that an Order has been selected from the grid
            if (selectedPOHeaderID == 0)
            {
                WarningHeaderMessage = "Warning!";
                WarningContentMessage = "Please select an Order from the grid.";
                Warning.OpenDialog();
            }
            else
            {
                //Create body of email using html
                emailbody = "<p>Dear Supplier</p>";
                emailbody = emailbody + "<p>Please click one of the following links (or copy and paste the link into your browser) to view our ";
                emailbody = emailbody + "order number " + selectedPOHeaderOrderNumber + " </p>";

                //without the anchor tag
                emailbody = emailbody + "<p>https://localhost:44377/previeworder/" + selectedPOHeaderGuid + "</p>";

                //with the anchor tag

                emailbody = emailbody + "<p><a href= "https://localhost:44377/previeworder/" + selectedPOHeaderGuid + "">https://localhost:44377/previeworder/" + selectedPOHeaderGuid + "<a></p>";

                emailbody = emailbody + "<p>Kind regards</p>";
                emailbody = emailbody + "<p>BlazorCode</p>";

                //MailKit
                //if (EmailService.Send(selectedPOHeaderSupplierEmail, "Purchase Order", emailbody))
                //SendGrid
                if (await EmailSender.SendEmail(selectedPOHeaderSupplierEmail, "Purchase Order", emailbody))
                {
                    //do something
                    await this.ToastObj.Show(Toast[1]);
                }
                else
                {
                    //do something else
                    await this.ToastObj.Show(Toast[2]);
                };
            }
        }
    }

    public void RowSelectHandler(RowSelectEventArgs<POHeader> args)
    {
        //{args.Data} returns the current selected records.
        selectedPOHeaderID = args.Data.POHeaderID;
        selectedPOHeaderGuid = args.Data.POHeaderGuid;
        selectedPOHeaderSupplierEmail = args.Data.POHeaderSupplierEmail;
        selectedPOHeaderOrderNumber = args.Data.POHeaderOrderNumber;
    }


    protected async Task ConfirmOrderArchive(bool archiveConfirmed)
    {
        if (archiveConfirmed)
        {
            orderHeader.POHeaderIsArchived = true;
            bool Success = await POHeaderService.POHeaderUpdate(orderHeader);
            await GetOrderList();
            StateHasChanged();
        }
    }

    protected async Task GetOrderList()
    {
        var user = (await authenticationStateTask).User;

        if (user.IsInRole("Admin") || user.IsInRole("Manager"))
        {
            poheader = await POHeaderService.POHeaderList(null);   //leave user name blank
        }
        else
        {
            poheader = await POHeaderService.POHeaderList(user.Identity.Name); //pass user name
        }
    }
}