有不同版本的 SendEmailAsync

Have different version of SendEmailAsync

我正在使用默认 ASP.NET MVC,身份模板...我想向我的客户发送一封确认电子邮件。

新项目模板附带的默认实现在AccountController.cs

中有一个注册方法
 public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email.Trim(), Email = model.Email.Trim(), FirstName = model.FirstName.Trim(), LastName = model.LastName.Trim() };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);

                // Send an email with this link
                string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                string message = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>";
                await UserManager.SendEmailAsync(user.Id, "Confirm your account", HttpUtility.UrlEncode(message));

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

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

有对UserManager.SendEmailAsync的调用,现在这个方法定义在Microsoft.AspNet.Identity中,我不想改变它。

真正的发送邮件功能在IdentityConfig.cs

public class SendGridEmailService : IIdentityMessageService
{
    public async Task SendAsync(IdentityMessage message)
    {
        var apiKey = ConfigurationManager.AppSettings["SendGridApiKey"];
        var client = new SendGridClient(apiKey);
        var msg = new SendGridMessage()
        {
            From = new EmailAddress("info@mycompany.com", "DX Team"),
            Subject = message.Subject,
            PlainTextContent = message.Body,
            HtmlContent = message.Body
        };

        msg.TemplateId = /* I want to pass templateId here */
        msg.Personalizations[0].Substitutions.Add("confirmurl", /* I want to pass Username here */);
        msg.Personalizations[0].Substitutions.Add("confirmurl", /* I want to pass confirm url here */);

        msg.AddTo(new EmailAddress("info@mycompant.com", "Test User"));
        var response = await client.SendEmailAsync(msg);

    }
}

现在如您所见,我正在使用 Sendgrid 发送电子邮件...所以我不想 message.body 发送电子邮件...我制作了一些模板,我想通过 teplate Id一些替换标签,例如要在模板中替换的用户名。

所以我不想要这种通用的 SendAsync 方法...我想要类似

的东西
SendGridAsync(SendGridMessage message)

是否可以添加这个方法,让我可以选择何时调用 SendAsync 以及何时调用 SendGridAsync?

您不需要使用内置的邮件服务,尤其是当您想做一些更复杂的事情时。

定义您自己的消息服务:

public interface IMyMessageService 
{
    Task SendConfirmationMessage(string confirmUrl, string to)
    // define methods for other message types that you want to send
}

public class MyMessageServie : IMyMessageService 
{
    public async Task SendConfirmationMessage(string confirmUrl, string to)
    {
        var apiKey = ConfigurationManager.AppSettings["SendGridApiKey"];
        var client = new SendGridClient(apiKey);
        var msg = new SendGridMessage()
        {
            From = new EmailAddress("info@mycompany.com", "DX Team"),
            Subject = message.Subject,
            PlainTextContent = message.Body,
            HtmlContent = message.Body
        };

        msg.TemplateId = /* I want to pass templateId here */
        msg.Personalizations[0].Substitutions.Add("confirmurl", confirmUrl);

        msg.AddTo(new EmailAddress(to, "Test User"));
        var response = await client.SendEmailAsync(msg);

    }
}

在您的 DI 框架中注册 IMyMessageService,并将其注入发送电子邮件的控制器(例如 AccountController)。

现在,您的注册操作将如下所示(假设我已注入 IMyMessageService 并在 _myMessageService 中有一个实例):

public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email.Trim(), Email = model.Email.Trim(), FirstName = model.FirstName.Trim(), LastName = model.LastName.Trim() };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);

            // Send an email with this link
            string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
            var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

            // USE YOUR MESSAGE SERVICE
            await _myMessageService.SendConfirmationMessage(callbackUrl, user.Email);

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

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