ASP.NET Core 3.1 创建发送邮件确认服务
ASP.NET Core 3.1 create a service to send email confirmation
我在几个页面上调用了方法 EmailConfirmation
,所以我决定为此创建一个服务。
但我对 GetEmailConfirmCallback
有疑问:Url
为空。
我也想更改身份区域页面并使用此服务,而不是在注册和外部登录等某些页面中,...每次都执行相同的任务。
这是我的 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;
}
}
如有任何建议或帮助,我们将不胜感激。
您是否尝试过使用 Url.Action
而不是 Url.Page
? Url.Action
用于 MVC,Url.Page
用于 Razor。您没有指定您使用的是 Razor 还是 MVC。
好的,这是过去的一些细节link
他们使用了 URL.Action 就像这个例子:
在您的代码中,您使用的是 Url.Page。
这是另一个使用 Url.Action 的例子:
- 在Startup.cs
中注册HttpContextAccessor
services.AddHttpContextAccessor();
- 在服务中添加
IHttpContextAccessor
和 LinkGenerator
作为依赖项注入 class
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly LinkGenerator _generator;
public ApplicationServices(UserManager<ApplicationUser> userManager,
IEmailSender emailSender,
IWebHostEnvironment webHostEnvironment,
IHttpContextAccessor httpContextAccessor,
LinkGenerator generator)
{
_userManager = userManager;
_emailSender = emailSender;
_webHostEnvironment = webHostEnvironment;
_httpContextAccessor = httpContextAccessor;
_generator = generator;
}
- 改变方法
GetEmailConfirmCallback
private async Task<string> GetEmailConfirmCallback(ApplicationUser user, HttpContext context, string returnUrl)
{
var codeEmail = await _userManager.GenerateEmailConfirmationTokenAsync(user);
codeEmail = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(codeEmail));
var callbackUrlEmail = _generator.GetUriByPage(_httpContextAccessor.HttpContext,
page:"/Account/ConfirmEmail",
handler: null,
values: new { area = "Identity", userId = user.Id, code = codeEmail, returnUrl });
return callbackUrlEmail;
}
我在几个页面上调用了方法 EmailConfirmation
,所以我决定为此创建一个服务。
但我对 GetEmailConfirmCallback
有疑问:Url
为空。
我也想更改身份区域页面并使用此服务,而不是在注册和外部登录等某些页面中,...每次都执行相同的任务。
这是我的 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;
}
}
如有任何建议或帮助,我们将不胜感激。
您是否尝试过使用 Url.Action
而不是 Url.Page
? Url.Action
用于 MVC,Url.Page
用于 Razor。您没有指定您使用的是 Razor 还是 MVC。
好的,这是过去的一些细节link
他们使用了 URL.Action 就像这个例子:
在您的代码中,您使用的是 Url.Page。
这是另一个使用 Url.Action 的例子:
- 在Startup.cs 中注册
HttpContextAccessor
services.AddHttpContextAccessor();
- 在服务中添加
IHttpContextAccessor
和LinkGenerator
作为依赖项注入 class
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly LinkGenerator _generator;
public ApplicationServices(UserManager<ApplicationUser> userManager,
IEmailSender emailSender,
IWebHostEnvironment webHostEnvironment,
IHttpContextAccessor httpContextAccessor,
LinkGenerator generator)
{
_userManager = userManager;
_emailSender = emailSender;
_webHostEnvironment = webHostEnvironment;
_httpContextAccessor = httpContextAccessor;
_generator = generator;
}
- 改变方法
GetEmailConfirmCallback
private async Task<string> GetEmailConfirmCallback(ApplicationUser user, HttpContext context, string returnUrl)
{
var codeEmail = await _userManager.GenerateEmailConfirmationTokenAsync(user);
codeEmail = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(codeEmail));
var callbackUrlEmail = _generator.GetUriByPage(_httpContextAccessor.HttpContext,
page:"/Account/ConfirmEmail",
handler: null,
values: new { area = "Identity", userId = user.Id, code = codeEmail, returnUrl });
return callbackUrlEmail;
}