Search code examples
asp.net-coreasp.net-web-apimailkit

ASP.NET Core Web API - How to send Registration Notification Email without link and token


In my ASP.NET Core-6 Web API, I am sending email notification to users when his user registration account is created.

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(string emailTempPath, string token, string email)
{
    var link = $"https://myapp.com/Manager/RegisterManager?email={email}&token={token}";
    var temp = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), emailTempPath));
    var emailBody = temp.Replace("**link**", link);
    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 result = await _userManager.CreateAsync(user, model.Password);
            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;
        };
    }

I want to send the Username and Password to the user as Email notification. This will not include link and token. And the will not confirm, but just to know his Username and password.

How do I modify the code above to achieve this?

Thanks


Solution

  • It seems you are using Microsoft.AspNetCore.Identity for the functionality. You can disable email verification as you intend to not require the user functionality.

    services.AddIdentity<ApplicationUser, IdentityRole>(config =>
    {
       config.SignIn.RequireConfirmedEmail = false;
    })
    

    And you can have your Username information from var user = _mapper.Map<AppUser>(model); and password from RegisterUserDto model, just construct the email body with these value and put it in mailBody variable.