After successfully registering users, I am sending user registeration notification to users through email. I am using ASP.NET Core-6 Web API MailKit.
MailService:
public class MailService : IMailService
{
private readonly MailSettings _mailSettings;
private readonly ILogger _logger;
public MailService(MailSettings mailSettings, ILogger logger)
{
_logger = logger;
_mailSettings = mailSettings;
}
public async Task<bool> SendEmailAsync(MailRequest mailRequest)
{
var email = new MimeMessage { Sender = MailboxAddress.Parse(_mailSettings.Mail) };
email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
email.Subject = mailRequest.Subject;
var builder = new BodyBuilder();
if (mailRequest.Attachments != null)
{
foreach (var file in mailRequest.Attachments.Where(file => file.Length > 0))
{
byte[] fileBytes;
await using (var ms = new MemoryStream())
{
file.CopyTo(ms);
fileBytes = ms.ToArray();
}
builder.Attachments.Add((file.FileName Guid.NewGuid().ToString()), fileBytes, ContentType.Parse(file.ContentType));
}
}
builder.HtmlBody = mailRequest.Body;
email.Body = builder.ToMessageBody();
try
{
using var smtp = new SmtpClient();
smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
smtp.Authenticate(_mailSettings.Mail, _mailSettings.Password);
await smtp.SendAsync(email);
smtp.Disconnect(true);
return true;
}
catch (Exception e)
{
_logger.Error(e, e.Source, e.InnerException, e.Message, e.ToString());
return false;
}
}
}
MailRequest:
public class MailRequest
{
public string ToEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public List<IFormFile> Attachments { get; set; }
}
GetEmailBody:
public static async Task<string> GetEmailBody(AppUser user, string emailTempPath)
{
var userName = textInfo.ToTitleCase(user.UserName);
var temp = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), emailTempPath));
var emailBody = temp.Replace("**User**", userName);
return emailBody;
}
Register:
public async Task<Response<string>> Register(RegisterUserDto model)
{
var user = _mapper.Map<AppUser>(model);
user.IsActive = true;
var response = new Response<string>();
using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
var rng = new Random();
ulong randomNumber = rng.NextULong(1000, 9999);
var userPassword = "@Password" randomNumber.ToString();
var result = await _userManager.CreateAsync(user, userPassword);
var result = await _userManager.CreateAsync(user, userPassword);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, UserRoles.Customer);
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var encodedToken = TokenConverter.EncodeToken(token);
var userRole = await _userManager.GetRolesAsync(user);
var mailBody = await EmailBodyBuilder.GetEmailBody(user, userRole.ToList(), emailTempPath: "StaticFiles/Html/ConfirmEmail.html", linkName: "ConfirmEmail", encodedToken, controllerName: "Authentication");
var mailRequest = new MailRequest()
{
Subject = "Registration Notification",
Body = mailBody,
ToEmail = model.Email
};
bool emailResult = await _mailService.SendEmailAsync(mailRequest);
if (emailResult)
{
_logger.Information("Mail sent successfully");
var customer = new Customer
{
AppUser = user
};
await _unitOfWork.Customers.InsertAsync(customer);
await _unitOfWork.Save();
response.StatusCode = (int)HttpStatusCode.Created;
response.Succeeded = true;
response.Data = user.Id;
response.Message = "User created successfully! Please check your mail to verify your account.";
transaction.Complete();
return response;
}
_logger.Information("Mail service failed");
transaction.Dispose();
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.Succeeded = false;
response.Message = "Registration failed. Please try again";
return response;
}
response.Message = GetErrors(result);
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.Succeeded = false;
transaction.Complete();
return response;
};
}
EmailTemplate:
<tr>
<td style="font-size: 14px; line-height: 1.8; padding: 10px 20px" >UserName: **User**,</td>
</tr>
<tr>
<td style="font-size: 14px; line-height: 1.8; padding: 10px 20px" >Password: **Password**,</td>
</tr>
From the EmailBodyBuilder, I've been able to send the UserName to the EmailTemplate.
How do I also send the auto-generated password (see it in Register - userPassword) from the EmailBodyBuilder to the EmailTemplate?
Thanks
CodePudding user response:
If that method doesn't enable you to send custom fields, you can construct your email body like this:
Html template
<tr>
<td style="font-size: 14px; line-height: 1.8; padding: 10px 20px">UserName: {0},</td>
</tr>
<tr>
<td style="font-size: 14px; line-height: 1.8; padding: 10px 20px">Password: {1},</td>
</tr>
Prepare body
var builder = new BodyBuilder();
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
builder.HtmlBody = SourceReader.ReadToEnd();
}
//{0} : Username
//{1} : GeneratedPassword
string messageBody = string.Format(builder.HtmlBody,
user.Username,
generatedPassword
);