【问题标题】:'Forgot Email' function not sending email“忘记电子邮件”功能不发送电子邮件
【发布时间】:2020-03-26 02:15:33
【问题描述】:

我正在构建我的第一个 ASP.NET Core Razor Pages 应用程序。

我创建了一个EmailSender 类,它实现了IEmailSender

public class EmailSender : IEmailSender
{
    private readonly EmailSettings Settings;

    public EmailSender(IOptions<EmailSettings> emailSettings)
    {
        Settings = emailSettings.Value;
    }

    public async Task SendEmailAsync(string email, string subject, string htmlMessage)
    {
        using (MailMessage message = new MailMessage())
        using (SmtpClient client = new SmtpClient())
        {
            client.Host = Settings.Host;
            client.Port = Settings.Port;
            client.Credentials = new NetworkCredential(Settings.UserName, Settings.Password);
            client.EnableSsl = Settings.EnableSsl;

            message.To.Add(email);
            message.From = new MailAddress(Settings.FromAddress);
            message.Subject = subject;
            message.Body = htmlMessage;
            message.IsBodyHtml = true;

            await client.SendMailAsync(message);
        }
        await Task.CompletedTask;
    }
}

我已经在 Startup.cs 中注册了EmailSender

public void ConfigureServices(IServiceCollection services)
{

    // Default initialization...

    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
}

我的代码构建没有错误。

使用断点,我可以看到当我运行应用程序并单击忘记密码时,EmailSender 构造函数被调用,EmailSettings 实例具有预期值。当我输入我的电子邮件地址并单击重设密码时,EmailSender 构造函数被第二次调用。但是,EmailSender.SendEmailAsync()从未被调用过,也没有发送电子邮件。

我确信我的EmailSender 类设置正确,因为正在调用构造函数。但我不知道如何找出从未调用过 SendEmailAsync() 的原因。

有人有什么建议吗?

【问题讨论】:

  • 我没有看到任何调用SendEmailAsync 的代码。这个方法是从哪里调用的?
  • @DeanOC:我的理解是它是从 ASP.NET 调用的。我为我的应用程序选择了具有本地用户存储库的选项,实际上,它生成了包含 忘记密码 链接的页面,该链接转到提示您输入电子邮件的页面。不幸的是,我无法调试该代码,甚至无法查看它的标记 (???)。
  • @DeanOC:this example 中的EmailSender 类似乎假设它也将从 ASP.NET 调用。而且,事实上,框架显然正在创建一个类的实例,正如我的构造函数被调用的事实所证明的那样。
  • 在您粘贴的链接中,有一个关于未发送电子邮件的反馈问题 #15830。这与您有关吗?
  • @DeanOC:很好的发现,因为我从没想过会这样。不幸的是,将 EmailConfirmed 列设置为 true 不会改变结果。 :-(

标签: c# asp.net-core asp.net-identity razor-pages


【解决方案1】:

脚手架标识

您需要搭建 Identity 才能调试代码。

右击Identity文件夹,然后点击

  • 添加 >> 新的脚手架项目..

在左侧菜单中点击

  • 身份>>添加

然后

  • 检查帐户\忘记密码
  • 选择您的数据库上下文类
  • 点击添加

现在您的剃须刀页面已包含代码,因此请单击箭头以展开代码隐藏文件。

PostAsync() 的 if 语句上放一个断点。

if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) // Breakpoint here
{
    ...
}

运行应用程序并执行忘记密码请求。

您的断点将命中,您将能够进行调试。它不会退出 if 语句,因为 await _userManager.IsEmailConfirmedAsync(user)false

通过将调试器拖到该循环之外来解决该问题,然后让它继续运行。现在您将看到您的电子邮件发件人将被调用并且您的 SendEmailAsync 将被命中。

总结一下

  • “神奇”登录、注销和帐户页面由身份团队通过库包提供给您。
  • 为了访问代码,您需要构建它们。
  • 您没有点击SendEmailAsync,因为您尝试为其请求密码的用户不存在很可能,您的用户的电子邮件未得到确认!

【讨论】:

  • 我不明白这个。我的应用程序已经有一个注册页面、一个登录页面、一个忘记密码页面等等。除了发送忘记密码电子邮件之外,一切似乎都正常。在我看来,这些页面已经为我设置好了。但显然它们是在框架内实现的。所以我对我需要搭建 Identity 的建议感到困惑。
  • Identity 会对您隐藏这些页面。它们是身份 UI 的一部分。为了访问它们 - 并对它们进行更改或调试它们 - 您必须构建代码。
  • 我会在早上调查这个。这是我第一次听说需要这个额外的步骤,所以我需要看看我是否能找到一些关于它的文档。
  • 我面前没有详细信息,但如果我按照上述步骤操作,我会收到运行时错误。在您提供的链接上阅读更多内容,我看到当我搭建 Identity 的一部分时创建了一个 TXT 文件。该文件讨论了所做的更改,并有额外的说明以使脚手架工作。这些说明包括对 Startup.cs 的更改,其中包括添加 AddMvc()。显然,脚手架生成的代码使用了 MVC。
【解决方案2】:

请确认您的AccountController 调用了IEmailSender.SendEmailAsync 方法。示例见此处:https://github.com/aspnet/AspNetCore.Docs/blob/master/aspnetcore/security/authentication/identity/sample/src/ASPNETCore-IdentityDemoComplete/IdentityDemo/Controllers/AccountController.cs#L375

ForgotPassword 动作中有一行:

await _emailSender.SendEmailAsync(model.Email, "Reset Password",
                   $"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");

【讨论】:

  • 我在 Razor 页面中看不到任何控制器。此外,正如我在问题中提到的,我什至看不到会员页面的标记(注册、登录、忘记密码等)。我不知道如何修改这些页面或它们背后的行为。跨度>
  • 哦,对不起,我忘了 Razor Pages 是不同的。您的项目应该有一个Pages 文件夹。更具体地说,它应该有Pages / Account / Manage。每个cshtml 文件都应该有一个关联的cs 文件,其中包含“代码隐藏”。
  • 它没有任何这些页面。在Areas 下,它有一个Identity 文件夹。但唯一的文件是 _ViewStart.cshtml。其他一切都必须在 ASP.NET 中。就个人而言,我不明白。这只是我需要弄清楚的关于 Razor Pages 的其他事情。
  • 你可以看到它的文档:github.com/oktadeveloper/…@JonathanWood
  • @RezaGhahari:看起来就是代码。但如果它嵌入在 ASP.NET 中,我该如何为我的应用程序定制它?
猜你喜欢
  • 2016-08-31
  • 2012-02-04
  • 1970-01-01
  • 2011-02-19
  • 2014-05-23
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 2014-11-30
相关资源
最近更新 更多