控件未命中自定义电子邮件服务的 SendAsync 功能:MVC 电子邮件确认

Control not hitting SendAsync function of Custom EmailService : MVC Email confirmation

我在 Visual Studio 2013 年创建了一个新的 MVC 项目。我注意到 IdentityConfig.cs 文件丢失了。我听说 Microsoft 已将其从较新版本的 ASP.NET Identity 中删除。此文件存在时用于定义 EmailService class.

所以我实现了我自己的 EmailService class。代码看起来像这样

//EmailService.cs
public class EmailService : IIdentityMessageService
{
    public async Task SendAsync(IdentityMessage message)
    {
        await configGMailAsync(message);
    }
    private static async Task configGMailAsync(IdentityMessage message)
    {
       //mailing code
    }
} 

在我的 AccountController 中,我有以下 Register 方法,它调用 UserManager.SendEmailAsync() 方法。

    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser() { UserName = model.UserName };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);

                var provider = new DpapiDataProtectionProvider("myAppName");
                UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"));
                string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);

                var callbackUrl = Url.Action("ConfirmEmail", "Account",
                    new { userId = user.Id, code = code },
                    protocol: Request.Url.Scheme);


                await UserManager.SendEmailAsync(user.Id,
                    "Confirm your account", "Please confirm your account by clicking <a href=\""
                    + callbackUrl + "\">here</a>");

                return RedirectToAction("Index", "Home");
            }
            else
            {
                AddErrors(result);
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

然而,在调用 UserManager.SendEmailAsync() 之后,控件(调试器)从未命中 EmailService class 的 SendAsync() 函数。

我有另一个项目,其中 IdentityConfig.cs 是在项目创建时自动添加的。在那里,在调用 UserManager.SendEmailAsync() 之后,控件会点击 SendAsync() 函数。

我在这里错过了什么?

事实证明,在发送邮件之前,您必须使用 UserManager class 注册您的服务。在 UserManager.SendEmailAsync() 上方添加以下行后,成功获取 SendAsync() 函数:

UserManager.EmailService = new EmailService();

这是包括新添加的行在内的完整功能

// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser() { UserName = model.UserName };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInAsync(user, isPersistent: false);

            var provider = new DpapiDataProtectionProvider("myAppName");
            UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"));
            string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);

            var callbackUrl = Url.Action("ConfirmEmail", "Account",
                new { userId = user.Id, code = code },
                protocol: Request.Url.Scheme);

            UserManager.EmailService = new EmailService();

            await UserManager.SendEmailAsync(user.Id,
                "Confirm your account", "Please confirm your account by clicking <a href=\""
                + callbackUrl + "\">here</a>");

            return RedirectToAction("Index", "Home");
        }
        else
        {
            AddErrors(result);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

我在 VS 2017 中使用个人用户帐户创建了一个新的 Web API 2 项目。存在 IdentityConfig.cs,但没有 EmailService class。如果是这种情况,并且您不想在每次不想使用此功能时都写 UserManager.EmailService = new EmailService();,则可以在此处添加它。

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
    manager.EmailService = new EmailService();