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;
}
}
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:
In your code you're using Url.Page.