CHAPTER 9

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

Figure 66: SendGrid NuGet Package
Install the SendGrid NuGet package.

Figure 67: EmailSender.cs
We will create a class that will read the settings from the appsettings.json file and send emails.
Create a new class in the Data folder called EmailSender.cs using the following code.
Code Listing 50: 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 in our code as a service, add the following line to the ConfigureServices section of the Startup.cs file.
Code Listing 51: EmailSender in Startup.cs
services.AddScoped<EmailSender>(); |
To send an email to the administrator when a new help desk ticket is created, open the Index.razor file and add the following line to inject the email service.
Code Listing 52: EmailSender Service
@inject EmailSender _EmailSender |
Next, add the following code to the end of the HandleValidSubmit method.
Code Listing 53: HandleValidSubmit method
// Send email. await _EmailSender.SendEmail( "Help Desk Ticket Created", "", // No need to pass an email because it goes to administrator. NewHelpDeskTickets.TicketGuid ); |
To send an email to the help desk ticket creator, when the help desk ticket is updated, open the Administration.razor file and add the following line to inject the email service.
Code Listing 54: EmailSender Service
@inject EmailSender _EmailSender |
Next, add the following code to the end of the SaveTicket method.
Code Listing 55: Send Email
// Send email to requester. await _EmailSender.SendEmail( "Help Desk Ticket Updated", SelectedTicket.TicketRequesterEmail, SelectedTicket.TicketGuid ); |
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.
Create a new control called EmailTicketEdit.razor with the following code.
Code Listing 56: 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 remaining code for the file.
Code Listing 57: EmailTicketEdit Code
@using Microsoft.Extensions.Configuration @using System.Security.Claims; @using SyncfusionHelpDesk.Data; @inject EmailSender _EmailSender @inject IConfiguration _configuration @inherits OwningComponentBase<SyncfusionHelpDeskService> <div id="target" style="height: 500px;"> @if (!EditDialogVisibility) { <h2>Your response has been saved</h2> <h4>Thank You!</h4> } </div> <SfDialog Target="#target" Width="500px" Height="500px" IsModal="true" ShowCloseIcon="true" Visible="EditDialogVisibility"> <DialogTemplates> <Header> EDIT TICKET # @SelectedTicket.Id</Header> <Content> <EditTicket SelectedTicket="@SelectedTicket" /> </Content> <FooterTemplate> <div class="button-container"> <button type="submit" class="e-btn e-normal e-primary" @onclick="SaveTicket"> Save </button> </div> </FooterTemplate> </DialogTemplates> </SfDialog> @code { [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; } [Parameter] public string TicketGuid { get; set; } ClaimsPrincipal CurrentUser = new ClaimsPrincipal(); private HelpDeskTickets SelectedTicket = new HelpDeskTickets(); private bool EditDialogVisibility = true; protected override async Task OnInitializedAsync() { // Get current user. CurrentUser = (await authenticationStateTask).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 @Service.GetHelpDeskTicketAsync(TicketGuid); StateHasChanged(); } } public async Task SaveTicket() { // Save the help desk ticket. var result = await @Service.UpdateTicketAsync(SelectedTicket); // Close the Dialog. EditDialogVisibility = false; // Send emails. if (CurrentUser.Identity.IsAuthenticated) { if (CurrentUser.IsInRole("Administrators")) { // 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 in both this page and the Administration page.
![]()
Figure 68: 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.
We've seen in this book how Blazor technology enables you to create sophisticated, manageable, and extensible single-page applications using C# and Razor syntax. Try it!