.Net Core Entity Framework 邮箱确认链接点击后EmailConfirmed未更新
问题根源
代码问题出在两个核心环节:
- 构造邮件正文时对生成的回调链接
callbackUrl做了多余的全量HTML编码,导致URL中的查询参数分隔符&被转义为& - 邮件发送逻辑中直接将带HTML标签和转义字符的内容同时赋值给了纯文本和HTML两种邮件格式的内容,导致邮箱客户端解析链接时出错,服务器收到请求时无法正确识别
code参数
解决方案
方案1:直接修复编码错误(推荐)
修改Register.cshtml.cs中构造邮件正文的代码,移除对callbackUrl的HtmlEncoder.Default.Encode调用:
// 原错误代码 // var mailBody = _loc.GetLocalizedString(CultureInfo.CurrentCulture.Name, "Please confirm your GatheringForGood account by <a href='{0}'>clicking here</a>.", HtmlEncoder.Default.Encode(callbackUrl)); // 替换为正确代码 var mailBody = _loc.GetLocalizedString(CultureInfo.CurrentCulture.Name, "Please confirm your GatheringForGood account by <a href='{0}'>clicking here</a>.", callbackUrl);
Url.Page生成的回调链接本身已经完成了URL编码,放在用引号包裹的href属性中无需额外做HTML全量编码。
方案2:优化邮件发送逻辑(可选,兼容纯文本邮件用户)
修改EmailSender.cs的发送逻辑,分开生成纯文本和HTML版本的邮件内容,避免转义字符出现在纯文本链接中:
// 先在Register.cshtml.cs中构造两个版本的内容 var htmlBody = _loc.GetLocalizedString(CultureInfo.CurrentCulture.Name, "Please confirm your GatheringForGood account by <a href='{0}'>clicking here</a>.", callbackUrl); var plainTextBody = _loc.GetLocalizedString(CultureInfo.CurrentCulture.Name, "Please confirm your GatheringForGood account by opening this link: {0}", callbackUrl); // 发送时传入两个版本的内容 await _emailSender.SendEmailAsync(Input.Email, mailHeader, plainTextBody, htmlBody); // 对应修改EmailSender的方法 public Task SendEmailAsync(string email, string subject, string plainTextMessage, string htmlMessage) { return Execute(Options.SendGridKey, subject, plainTextMessage, htmlMessage, email); } public Task Execute(string apiKey, string subject, string plainTextMessage, string htmlMessage, string email) { var client = new SendGridClient(apiKey); var msg = new SendGridMessage() { From = new EmailAddress("info@myemail.com", Options.SendGridUser), Subject = subject, PlainTextContent = plainTextMessage, HtmlContent = htmlMessage }; msg.AddTo(new EmailAddress(email)); msg.SetClickTracking(false, false); return client.SendEmailAsync(msg); }
临时兼容方案(如果无法立即修改上游逻辑)
如果暂时无法修改邮件生成逻辑,可以在ConfirmEmail.cshtml.cs的OnGetAsync方法最开头增加手动参数兼容逻辑:
public async Task<IActionResult> OnGetAsync(string userId, string code) { // 兼容被错误转义的参数 if (string.IsNullOrEmpty(code) && Request.Query.ContainsKey("amp;code")) { code = Request.Query["amp;code"]; } // 原有逻辑不变 if (userId == null || code == null) { return RedirectToPage("/Index", new { culture }); } // ... 其余原有代码保持不变 }
内容的提问来源于stack exchange,提问作者DMur
相关产品推荐
相关产品推荐

