CHAPTER 10
Sending Emails

Figure 70: Email process
In this chapter, we will create code that will allow help desk ticket creators and administrators to update tickets by navigating to that help desk ticket record and clicking a link in an email.
We will also write code that will email the administrators when a new help desk ticket has been created, as well as code that will email help desk ticket creators and administrators when help desk tickets are updated.
Email using SendGrid
To enable emails, create a free SendGrid account at https://sendgrid.com/ and obtain an email API key using the following steps:
- Open the appsettings.json file and add the following two lines from Code Listing 54 below the opening curly bracket, entering your SendGrid key for the SENDGRID_APIKEY property and your email address for the SenderEmail property:
Code Listing 54: appsettings.json
"SENDGRID_APIKEY": "{{ enter your key from app.sendgrid.com }}", "SenderEmail": "{{ enter your email address }}", |

Figure 71: SendGrid NuGet package
- Install the SendGrid NuGet package.
Email sender class

Figure 72: EmailSender.cs
Now, we will create a class that will read the settings from the appsettings.json file and send emails by using the following steps:
- Create a new class in the Services folder called EmailSender.cs by using the code from Code Listing 55.
Code Listing 55: EmailSender.cs
using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using SendGrid; using SendGrid.Helpers.Mail; namespace SyncfusionHelpDesk { public class EmailSender { private readonly IConfiguration configuration; private readonly IHttpContextAccessor httpContextAccessor; public EmailSender( IConfiguration Configuration, IHttpContextAccessor HttpContextAccessor) { configuration = Configuration; httpContextAccessor = HttpContextAccessor; } public async Task SendEmail( string EmailType, string EmailAddress, string TicketGuid) { try { // Email settings SendGridMessage msg = new SendGridMessage(); var apiKey = configuration["SENDGRID_APIKEY"]; var senderEmail = configuration["SenderEmail"]; var client = new SendGridClient(apiKey); var FromEmail = new EmailAddress( senderEmail, senderEmail ); // Format Email contents string strPlainTextContent = $"{EmailType}: {GetHelpDeskTicketUrl(TicketGuid)}"; string strHtmlContent = $"<b>{EmailType}:</b> "; strHtmlContent = strHtmlContent + $"<a href='{ GetHelpDeskTicketUrl(TicketGuid) }'>"; strHtmlContent = strHtmlContent + $"{GetHelpDeskTicketUrl(TicketGuid)}</a>"; if (EmailType == "Help Desk Ticket Created") { msg = new SendGridMessage() { From = FromEmail, Subject = EmailType, PlainTextContent = strPlainTextContent, HtmlContent = strHtmlContent }; // Created Email always goes to Administrator // Send to senderEmail configured in appsettings.json msg.AddTo(new EmailAddress(senderEmail, EmailType)); } if (EmailType == "Help Desk Ticket Updated") { msg = new SendGridMessage() { From = FromEmail, Subject = EmailType, PlainTextContent = strPlainTextContent, HtmlContent = strHtmlContent }; // Updated emails go to Administrator or Ticket creator // Send to EmailAddress passed to method msg.AddTo(new EmailAddress(EmailAddress, EmailType)); } var response = await client.SendEmailAsync(msg); } catch { // Could not send email // Perhaps SENDGRID_APIKEY not set in // appsettings.json } } // Utility #region public string GetHelpDeskTicketUrl(string TicketGuid) public string GetHelpDeskTicketUrl(string TicketGuid) { var request = httpContextAccessor.HttpContext?.Request; var host = request?.Host.ToUriComponent(); var pathBase = request?.PathBase.ToUriComponent(); return $@"{request?.Scheme}://{host}{pathBase}/emailticketedit/{TicketGuid}"; } #endregion } } |
- To allow this class to be injected into our code as a service, add the following line to the ConfigureServices section of the Program.cs file:
Code Listing 56: EmailSender in Program.cs
builder.Services.AddScoped<EmailSender>(); |
Send emails: New help desk ticket
To send an email to the administrator when a new help desk ticket is created:
- Open the Home.razor file and add the line from Code Listing 57 to inject the email service.
Code Listing 57: Inject EmailSender s3ervice
@inject EmailSender _EmailSender |
- Next, add the following code to the end of the HandleValidSubmit method.
Code Listing 58: HandleValidSubmit method
// Send Email await _EmailSender.SendEmail( "Help Desk Ticket Created", "", // No need to pass an email because it goes to Administrator NewHelpDeskTickets.TicketGuid ); |
Send emails: Updated help desk ticket
To send an email to the help desk ticket creator when the ticket is updated:
- Open the Tickets.razor file and add the line from Code Listing 59 to inject the email service.
Code Listing 59: Add EmailSender service to tickets
@inject EmailSender _EmailSender |
- Next, add the following code to the end of the SaveTicket method:
Code Listing 60: Send email
// Send email to Requester await _EmailSender.SendEmail( "Help Desk Ticket Updated", SelectedTicket.TicketRequesterEmail, SelectedTicket.TicketGuid ); |
Route parameters
When a help desk ticket is initially created and saved to the database, it is assigned a unique GUID value. When an email is sent to notify the help desk ticket creator and administrator, the email will contain a link that passes this GUID to the Blazor control that we will create. This control will be decorated with a @page directive that contains a route parameter. To implement route parameters:
- Create a new control called EmailTicketEdit.razor with the following code:
Code Listing 61: EmailTicketEdit route
@page "/emailticketedit/{TicketGuid}" |
This line, together with a field in the @code section called TicketGuid (of type string), will allow this control to be loaded and passed a value for TicketGuid from a link in the email.
- Enter the following code as the markup code for the file:
Code Listing 62: EmailTicketEdit markup code
@using Microsoft.EntityFrameworkCore @using Microsoft.Extensions.Configuration @using System.Security.Claims; @using SyncfusionHelpDesk.Data; @using SyncfusionHelpDesk.Models @inject EmailSender _EmailSender @inject IConfiguration _configuration @inject AuthenticationStateProvider AuthenticationStateProvider @inject IDbContextFactory<SyncfusionHelpDeskContext> DbFactory @inject SyncfusionHelpDeskService SyncfusionHelpDeskService <style> .custom-dialog .e-dialog { max-height: 90vh !important; /* Customize the max height */ } </style> <div id="target" style="height: 500px;"> @if (!EditDialogVisibility) { <h2>Your response has been saved</h2> <h2>Thank You!</h2> } </div> <SfDialog Target="#target" CssClass="custom-dialog" Width="500px" IsModal="true" ShowCloseIcon="true" Visible="EditDialogVisibility"> <DialogTemplates> <Header> EDIT TICKET # @SelectedTicket.Id</Header> <Content> <EditTicket SelectedTicket="@SelectedTicket" /> </Content> <FooterTemplate> <div class="button-container"> <SfButton CssClass="e-primary" OnClick="SaveTicket">Save</SfButton> </div> </FooterTemplate> </DialogTemplates> </SfDialog> |
- Finally, enter the following code for the file:
Code Listing 63: EmailTicketEdit code
@code { #nullable disable [Parameter] public string TicketGuid { get; set; } ClaimsPrincipal CurrentUser = new ClaimsPrincipal(); private HelpDeskTicket SelectedTicket = new HelpDeskTicket(); private bool EditDialogVisibility = true; private string ADMINISTRATION_ROLE = "Administrators"; protected override async Task OnInitializedAsync() { // Get current user var authState = await AuthenticationStateProvider .GetAuthenticationStateAsync(); CurrentUser = authState.User; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { // Get the Help Desk Ticket associated with // the GUID that was passed to the control SelectedTicket = await SyncfusionHelpDeskService .GetHelpDeskTicketAsync(DbFactory, TicketGuid); StateHasChanged(); } } public async Task SaveTicket() { // Save the Help Desk Ticket var result = await SyncfusionHelpDeskService .UpdateTicketAsync(DbFactory, SelectedTicket); // Close the Dialog EditDialogVisibility = false; // Send Emails if (CurrentUser.Identity.IsAuthenticated) { if (CurrentUser.IsInRole(ADMINISTRATION_ROLE)) { // User an Administrator // Send email to Requester await _EmailSender.SendEmail( "Help Desk Ticket Updated", SelectedTicket.TicketRequesterEmail, SelectedTicket.TicketGuid ); return; } } // User is not an Administrator // Send email to Administrator string AdministratorEmail = _configuration["SenderEmail"]; await _EmailSender.SendEmail( "Help Desk Ticket Updated", AdministratorEmail, SelectedTicket.TicketGuid ); } } |
Notice that this page also includes the EditTicket control, effectively reusing that control for both this page and the tickets page.
Email link

Figure 73: Ticket created email link
When we run the application and create a new help desk ticket, the administrator is sent an email with a link. Clicking that link will take the administrator directly to the help desk ticket.

Figure 74: Ticket updated email link
When the administrator responds to the ticket, the user is sent an email with a link to the ticket that allows them to view and update the ticket.
- 80+ high performance Blazor components.
- Lightweight and user friendly.
- Stunning Built-in themes with customization.