将 Microsoft Identity 中的帐户激活 url 添加到 SendGrid 电子邮件动态模板 - ASP .NET

问题描述

我创建了一个 Asp.net 项目并添加了 Identity。我想使用 SendGrid 动态电子邮件模板(不是 LegacyTemplates)进行帐户确认。基本上,我想在 SendGrid 模板中的按钮上插入由 microsoft idendity 生成的令牌。我该怎么做?

这是我的代码

public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public AuthMessageSenderOptions Options { get; }

        public Task SendEmailAsync(string email,string subject,string message)
        {
            return Execute(Options.SendGridKey,subject,message,email);
        }

        public Task Execute(string apiKey,string message,string email)
        {
            apiKey = "api key";
            var client = new SendGridClient(apiKey);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress("my email",Options.SendGridUser),Subject = subject,PlainTextContent = message,HtmlContent = message,};

            SetTemplateId("Template Code");
            msg.AddTo(new EmailAddress(email));
            msg.SetClickTracking(false,false);

            return client.SendEmailAsync(msg);
        }

模板:

enter image description here

解决方法

您可以使用 SubstitutionTags

我是这样做的:

我创建了一个 EmailBase 类:

public abstract class EmailBase 
{
    public EmailBase()
    {
        ToDisplayName = string.Empty;
        ToFullName = string.Empty;
        FromDisplayName = string.Empty;
        FromFullName = string.Empty;
        Subject = string.Empty;
        Content = string.Empty;
        HtmlContent = string.Empty;
        TemplateId = string.Empty;
    }

    // note that I am using a default Sender email,you can modify this...
    public EmailBase(string toFirstName,string toLastName,string toEmail)
    {
        ToDisplayName = toFirstName;
        ToFullName = toFirstName + " " + toLastName;
        ToEmail = toEmail;
        FromDisplayName = string.Empty;
        FromEmail = "mailer@my-domain.com"; // I am using a default sender email
        FromFullName = "my-domain support"; // Whatever name you want for this email
        ReplyToEmail = string.Empty;
        ReplyToFullName = string.Empty;
        Subject = string.Empty;
        Content = string.Empty;
        HtmlContent = string.Empty;
        TemplateId = string.Empty;
        Attachment = null;
        AttachmentFileName = string.Empty;
    }

    public string ToDisplayName { get; set; }

    public string ToEmail { get; set; }

    public string ToFullName { get; set; }

    public string FromDisplayName { get; set; }

    public string FromEmail { get; set; }

    public string FromFullName { get; set; }

    public string ReplyToEmail { get; set; }

    public string ReplyToFullName { get; set; }

    public string Subject { get; set; }

    public string Content { get; set; }

    public string HtmlContent { get; set; }

    public string TemplateId { get; set; }

    public byte[] Attachment { get; set; }

    public string AttachmentFileName { get; set; }

    public Dictionary<string,string> SubstitutionTags { get; set; }
}

现在对于每个模板,您都可以创建一个继承自 EmailBase 的相应类,例如您可以为此模板创建 EmailAddressConfirmationEmail

public class EmailAddressConfirmationEmail : EmailBase
{
    public EmailAddressConfirmationEmail(string toFirstName,string toEmail,string embededUrl)
            : base(toFirstName,toLastName,toEmail)
    {
        // by default from is set to mailer@my-domain.com

        TemplateId = "your-template-id";

        SubstitutionTags = new Dictionary<string,string>
        {
            { "-name-",ToDisplayName },{ "-confirmationurl-",embededUrl }
        };
    }
}

最后,您可以通过以下方式创建电子邮件服务以生成您的 SendGridMessage

public class SendGridEmailService
{
    private readonly string _apiKey;

    public SendGridEmailService(string apiKey)
    {
        _apiKey = apiKey;
    }

    public int SendEmail(EmailBase email)
    {
        var client = new SendGridClient(_apiKey);
        Task<int> task = Task.Run<int>(async () => await SendEmailAsync(email));
        return task.Result;
    }

    public async Task<int> SendEmailAsync(EmailBase email)
    {
        var client = new SendGridClient(_apiKey);
        var sendGridMessage = BuildSendGridMessage(email);
        var response = await client.SendEmailAsync(sendGridMessage);

        return (int)response.StatusCode;
    }

    /*
     * This is the important function which builds SendGridMessage,* Note how we are using SubstitutionTags to achieve what you want
     */
    private SendGridMessage BuildSendGridMessage(EmailBase email)
    {
        SendGridMessage sendGridMessage = new SendGridMessage
        {
            From = new EmailAddress(email.FromEmail,email.FromFullName)
        };

        if (!string.IsNullOrEmpty(email.ReplyToEmail))
        {
            sendGridMessage.ReplyTo = new EmailAddress(email.ReplyToEmail,email.ReplyToFullName);
        }

        sendGridMessage.AddTo(new EmailAddress(email.ToEmail,email.ToFullName));
        if (!string.IsNullOrEmpty(email.TemplateId))
        {
            sendGridMessage.SetTemplateId(email.TemplateId);
            sendGridMessage.Personalizations[0].Substitutions = new Dictionary<string,string>();
            foreach (KeyValuePair<string,string> p in email.SubstitutionTags)
            {
                sendGridMessage.Personalizations[0].Substitutions.Add(p.Key,p.Value);
            }
        }

        if (!string.IsNullOrEmpty(email.Subject))
        {
            sendGridMessage.Subject = email.Subject;
        }

        if (!string.IsNullOrEmpty(email.Content))
        {
            sendGridMessage.AddContent("text/plain",email.Content);
        }

        if (!string.IsNullOrEmpty(email.HtmlContent))
        {
            sendGridMessage.HtmlContent = email.HtmlContent;
        }

        if (email.Attachment != null && !string.IsNullOrEmpty(email.AttachmentFileName))
        {
            using (WebClient webClient = new WebClient())
            {
                var base4File = Convert.ToBase64String(email.Attachment);
                sendGridMessage.AddAttachment(email.AttachmentFileName,base4File);
            }
        }

        return sendGridMessage;
    }
}