ASP.NET Identity UserManager IIdentityMessageService将额外参数传递给SendAsync

时间:2016-12-19 12:04:23

标签: c# asp.net asp.net-web-api asp.net-identity-2

我通过扩展IIdentityMessageService为UserManager成功创建了自定义电子邮件服务提供商:

public class ExchangeEmailService : IIdentityMessageService
{
    public async Task SendAsync(IdentityMessage message)
    {
        using (var client = new SmtpClient())
        {
            client.Host = "mail.example.com";
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.UseDefaultCredentials = false;
            client.Credentials = new NetworkCredential(@"noreply", "P@ssw0rd");

            var from = new MailAddress("no-reply@example.com");
            var to = new MailAddress(message.Destination);

            var mailMessage = new MailMessage(from, to)
            {
                Subject = message.Subject,
                Body = message.Body,
                IsBodyHtml = true
            };
            await client.SendMailAsync(mailMessage);
        }
    }
}

UserManager内创建我创建新服务实例并将其分配给EmailService

userManager.EmailService = new ExchangeEmailService();

这一切都运行正常,但我要求发送来自不同电子邮件地址的电子邮件,根据调用的地方,不幸的是UserManager.SendEmailAsync不允许我传递除userId,主题和正文之外的任何内容

理想情况下,我希望在调用SendEmailAcync或枚举值时能够指定电子邮件地址。

我已经在UserManager source中进行了搜索,我考虑过创建自定义SendEmailAsync实现,但我必须更改多个位置--IIdentityMessageService,UserManager。

我知道我可以创建新界面并在其上构建我的电子邮件发送课程,但我希望将更改保持在最低限度。

我想得到什么:
我想要包含邮箱名称的枚举:

public enum Mailboxes
{
    Noreply = 0,
    Service = 1,
    Contact = 2
}

并且可以使用其他参数调用SendEmailAsync

await UserManager.SendEmailAsync(user.Id, "Account created", "Nice email content.", Mailboxes.Noreply );

我知道我可以设置不同的标题并使用相同的电子邮件地址,但这是我的要求。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

黑客就是创建一个模型来存储你想要发送给服务的内容

public class MessageBody {
    public string Body { get; set; }
    public MailBoxes Source { get; set; }
}

然后将其序列化(可能是JSON)作为body方法调用的SendEmailAsync参数。

var message = new MessageBody {
    Body = "Nice email content.",
    Source = Mailboxes.Noreply
};

var body = JsonConvert.SerializeObject(message);

await UserManager.SendEmailAsync(user.Id, "Account created", body);

然后,该服务将反序列化模型,使用自定义信息构建电子邮件,然后发送电子邮件。

public class ExchangeEmailService : IIdentityMessageService {
    readonly IMailBoxProvider provider;

    public ExchangeEmailService(IMailBoxProvider provider) {
        this.provider = provider;
    }

    public async Task SendAsync(IdentityMessage message) {
        using (var client = new SmtpClient()) {
            client.Host = "mail.example.com";
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.UseDefaultCredentials = false;
            client.Credentials = new NetworkCredential(@"noreply", "P@ssw0rd");

            //Get the body and from address
            var fromEmailAddress = "default-email@example.com";
            var body = message.Body;
            try {
                var msg = JsonConvert.DeserializeObject<MessageBody>(body);
                if(msg != null) {
                    body = msg.Body;
                    fromEmailAddress = provider.GetMailbox(msg.Source);
                }
            } catch { }

            var from = new MailAddress(fromEmailAddress);
            var to = new MailAddress(message.Destination);

            var mailMessage = new MailMessage(from, to)
            {
                Subject = message.Subject,
                Body = body,
                IsBodyHtml = true
            };
            await client.SendMailAsync(mailMessage);
        }
    }
}

并确保将其分配给UserManager.EmailService

userManager.EmailService = new ExchangeEmailService(new MailBoxProvider());