【发布时间】:2021-08-29 20:14:33
【问题描述】:
我已按照此处 Microsoft 的说明在我的 .Net 5.0 应用中为我的用户注册电子邮件确认设置了 SendGrid:http://go.microsoft.com/fwlink/?LinkID=532713
在用户单击注册确认电子邮件中的确认链接之前,一切正常。
这个问题是由我的确认链接中的杂散放大器引起的。我正在尝试了解它的来源以及如何删除它。
当新用户在Register.cshtml 页面上单击“提交”时,他们会成功定向到RegisterConfirmation.cshtml 页面,并且电子邮件会在他们的收件箱中收到。
实际行为:
用户单击电子邮件中的链接并点击ConfirmEmail 页面。
用户被重定向到/Index页面。
数据库中的EmailConfirmed bool 未更新。
如果我在控制器中注释掉到 /Index 的重定向,则会收到如下所示的空值错误。
//if (userId == null || code == null)
//{
// return RedirectToPage("/Index", new { culture });
//}
但是,查询选项卡显示 userId 和 code 是正确的。
预期行为:
用户点击电子邮件中的链接。
数据库中的EmailConfirmed 布尔值IS已更新。
用户看到带有成功消息的ConfirmEmail 页面。
ConfirmEmail.cshtml.cs
using System;
snip...
namespace MyApp.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ConfirmEmailModel : PageModel
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ISharedCultureLocalizer _loc;
private readonly string culture;
readonly ConfirmEmailPageLocSourceNames _locSourceConfirmEmailPageNameReferenceLibrary = new ConfirmEmailPageLocSourceNames();
readonly SharedCrossPageLocSourceNames _locSourceSharedCrossPageNameReferenceLibrary = new SharedCrossPageLocSourceNames();
public ConfirmEmailModel(UserManager<ApplicationUser> userManager, ISharedCultureLocalizer loc)
{
_userManager = userManager;
_loc = loc;
culture = System.Globalization.CultureInfo.CurrentCulture.Name;
}
[TempData]
public string StatusMessage { get; set; }
snip...
public async Task<IActionResult> OnGetAsync(string userId, string code)
{
snip...
if (userId == null || code == null)
{
return RedirectToPage("/Index", new { culture });
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
var msg = _loc.GetLocalizedString("Unable to load user with ID '{0}'.", userId);
return NotFound(msg);
}
code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
var result = await _userManager.ConfirmEmailAsync(user, code);
if (result.Succeeded)
{
var msg = _loc.GetLocalizedString("Thank you for confirming your email.");
TempData.Success(msg);
}
else
{
var msg = _loc.GetLocalizedString("Error confirming your email.");
TempData.Danger(msg);
}
return Page();
}
}
}
RegisterConfirmation.cshtml.cs
using Microsoft.AspNetCore.Authorization;
snip...
namespace MyApp.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailSender _sender;
readonly RegisterConfPageLocSourceNames _locSourceRegisterConfPageNameReferenceLibrary = new RegisterConfPageLocSourceNames();
readonly SharedCrossPageLocSourceNames _locSourceSharedCrossPageNameReferenceLibrary = new SharedCrossPageLocSourceNames();
public RegisterConfirmationModel(UserManager<ApplicationUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
public string Email { get; set; }
snip...
public async Task<IActionResult> OnGetAsync(string email)
{
PageTabTitle = _locSourceRegisterConfPageNameReferenceLibrary.GetLocSourcePageTabTitleNameReferenceForRegisterConfPage();
snip...
if (email == null)
{
return RedirectToPage("/Index");
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
return Page();
}
}
}
Register.cshtml.cs
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
Debug.WriteLine("**************** " + code);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
Debug.WriteLine("**************** 1 *** " + code);
var callbackUrl = Url.Page("/Account/ConfirmEmail", pageHandler: null, values: new { area = "Identity", userId = user.Id, code = code, culture }, protocol: Request.Scheme);
var mailHeader = _loc.GetLocalizedString("Confirm your GatheringForGood email");
var mailBody = _loc.GetLocalizedString(CultureInfo.CurrentCulture.Name, "Please confirm your GatheringForGood account by <a href='{0}'>clicking here</a>.", HtmlEncoder.Default.Encode(callbackUrl));
await _emailSender.SendEmailAsync(Input.Email, mailHeader, mailBody);
EmailSender.cs 中的函数
public Task SendEmailAsync(string email, string subject, string message)
{
return Execute(Options.SendGridKey, subject, message, email);
}
public Task Execute(string apiKey, string subject, string message, string email)
{
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("info@myemail.com", Options.SendGridUser),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(email));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
return client.SendEmailAsync(msg);
}
更新:
在我的日志中的回调字符串中显示
userId=362c17ae-7854-42fb-91c3-efb19cc875f2&code=
但在 gmail 中收到的链接显示
userId=362c17ae-7854-42fb-91c3-efb19cc875f2&code=
在 Postman 中测试,这绝对是问题所在。我需要电子邮件正文中的链接看起来像这样。注意没有放大器;
https://localhost:44305/en/Identity/Account/ConfirmEmail?userId=d62d4727-f6ce-493c-bcf3-eb85a50a914f&code=Q2ZESjhKbkE2NU5BVk85S2drRnMvV3VtZXBySVFlTHZrQlNvUU9xbUxrYWQ5NjFDV0NvZGY1eHVCK01SSHVIL3EwMjEwYk8rU1lLaHJ4UHF1VS84RjJQTThBWlY4VHZTcGcrQVpiZU9wWHFyWnlsVkFpSFVUV3lIMGJjaG14aFJKQkgxNjZoQkVNM3ZETnR2WHhoZmx0ZnhQR095azdDREJVZVdJN01CTTRCcFptejJvSURjNHloZHdxRDl0UCs0eEdic1NMK25wbnFqb0xhdHFoR3M3T3BkTElhbG5TVU9obTJaTFpvc0xUb0RINzM2UmFBTVlrakZWL2VsV0YvUEJSaE1HQT09
【问题讨论】:
-
您必须编写代码来进行更新。 Stack Overflow 不存在为您执行此操作。
-
该评论显然没有帮助。我按照 Microsoft 的标识框架电子邮件确认说明进行操作,但它不起作用。我试过自己弄清楚,但我很难过。
-
“实体框架”搭建的身份页面。
-
@DMur - 你永远不会表明你正在使用实体框架UI,其中有很多东西为你搭建了脚手架。在教程中提供第四课(或其他课程)的链接对读者的期望太高了!我认为您的问题是有效的,但值得重写...
-
&amp;在 html 中通常非常好。发生这种情况是因为您在Register.cshtml的 url 上调用了HtmlEncoder.Default.Encode..。
标签: asp.net .net asp.net-core asp.net-identity