Home > Blockchain >  ASP.NET Core 3.1 create a service to send email confirmation
ASP.NET Core 3.1 create a service to send email confirmation

Time:12-22

I call the method EmailConfirmation on several pages so I decided to create a service for this.

But I have a problem with GetEmailConfirmCallback: Url is null.

I would like to change Identity area pages also and use this service instead of in some pages like register and externalLogin,... each time do the same task.

This is my class:

public class ApplicationServices : ControllerBase
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IEmailSender _emailSender;
    private readonly IWebHostEnvironment _webHostEnvironment;

    public ApplicationServices(IEmailSender emailSender, UserManager<ApplicationUser> userManager, IWebHostEnvironment webHostEnvironment)
    {
        _emailSender = emailSender;
        _userManager = userManager;
        _webHostEnvironment = webHostEnvironment;
    }

    public async Task<ResultModel> EmailConfirmation(ApplicationUser user, string returnUrl = "/Identity/Account/Login")
    {
        ResultModel resultModel = new ResultModel();

        try
        {
            var pathToEmailTemplate = _webHostEnvironment.WebRootPath
              Path.DirectorySeparatorChar.ToString()
              "templates"
              Path.DirectorySeparatorChar.ToString()
              "email_templates"
              Path.DirectorySeparatorChar.ToString()
              "confirm-email-reset-password.html";

            string emailTemplateString = string.Empty;

            using (StreamReader SourceReader = System.IO.File.OpenText(pathToEmailTemplate))
            {
                emailTemplateString = SourceReader.ReadToEnd();
            }

            string messageSubject = "Confirm your email";
            string messageBody = $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(await GetEmailConfirmCallback(user, returnUrl))}'>clicking here</a>.";

            string messageSenderName = "Support team.";

            string emailMessage = string.Format(emailTemplateString, messageSubject, string.IsNullOrEmpty(user.FullName) ? user.FullName : "User", messageBody, messageSenderName);

            await _emailSender.SendEmailAsync(user.Email, messageSubject, emailMessage);

            resultModel.IsSucceed = true;
            return resultModel;
        }
        catch (Exception e)
        {
            resultModel.IsSucceed = false;
            resultModel.Message = e.Message;
            return resultModel;
        }
    }
    
    private async Task<string> GetEmailConfirmCallback(ApplicationUser user, string returnUrl)
    {
        var codeEmail = await _userManager.GenerateEmailConfirmationTokenAsync(user);
        codeEmail = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(codeEmail));
        var callbackUrlEmail = Url.Page(
        "/Account/ConfirmEmail",
        pageHandler: null,
        values: new { area = "Identity", userId = user.Id, code = codeEmail, returnUrl },
        protocol: Request.Scheme);

        return callbackUrlEmail;
    }
}

Debug image 1

Debug image 2

Any advice or assistance would be greatly appreciated.

CodePudding user response:

Have you tried using Url.Action instead of Url.Page? Url.Action is for MVC and Url.Page is for Razor. You are not specifying if you are using Razor or MVC.

CodePudding user response:

Ok, here are some detail from the past link

They used a URL.Action like this example: enter image description here

In your code you're using Url.Page.

This is other exmaple that uses Url.Action: enter image description here

  • Related