Simone Spagna
Simone Spagna

Reputation: 636

Issue with substitution in sendgrid

I've to send a mail with substitution using sendgrid. I use the following code :

    public async Task SendConfirmationMailAsync(UserCreateViewModel model, string domain, ApplicationUser user)
    {
        string q = _encryption.EncryptText(model.Email + "|" + model.Password, _configuration["Security:EncryptionKey"]);
        string encryptdetexturl = HttpUtility.UrlEncode(q);
        string url = domain + "/Device/RegisterDevice?q=" + encryptdetexturl;


        Dictionary<string, string> substitution = new Dictionary<string, string>();
        substitution.Add("-indirizzo_email-", url);

        await _emailService.SendEmailAsync(user.Email, "d-1201e63adfa04976ba9fc17212172fe9", substitution);
    }

that calls

    public async Task SendEmailAsync(ApplicationUser applicationUser, string templateId)
    {
        var apiKey = _configuration["Email:apikey"];

        var client = new SendGridClient(apiKey);

        var from = new EmailAddress(_configuration["Email:Email"]);
        var to = new EmailAddress(applicationUser.Email);

        var substitutions = GetReplacement(applicationUser);

        var msg = MailHelper.CreateSingleTemplateEmail(from, to, templateId, null,substitutions);

        var response = await client.SendEmailAsync(msg);

        Trace.WriteLine(msg.Serialize());
        Trace.WriteLine(response.StatusCode);
        Trace.WriteLine(response.Headers);
    }

that calls

    public static SendGridMessage CreateSingleTemplateEmail(
                                                    EmailAddress from,
                                                    EmailAddress to,
                                                    string templateId,
                                                    object dynamicTemplateData,
                                                    Dictionary<string, string> substitutions)
    {
        if (string.IsNullOrWhiteSpace(templateId))
        {
            throw new ArgumentException($"{nameof(templateId)} is required when creating a dynamic template email.", nameof(templateId));
        }

        var msg = new SendGridMessage();
        msg.SetFrom(from);
        msg.AddTo(to);
        msg.TemplateId = templateId;

        if (dynamicTemplateData != null)
        {
            msg.SetTemplateData(dynamicTemplateData);
        }

        if (substitutions != null)
        {
            msg.AddSubstitutions(substitutions);
        }

        return msg;
    }

The send process alwais fails probably because in the third method I've separated dynamicTemplateData and substitutions. I have to send a message that refers to a templeate stored in sendgrid and and i haven't to pass it to the method.

The Sendgrid error is the following :

{"from":{"email":"[email protected]"},"personalizations":[{"to":[{"email":"[email protected]"}],"substitutions":{"-indirizzo_email-":"https://localhost:44391/Device/RegisterDevice?q=tnGdfw1EojMggP15KY39IWJGE9GkYWOTzMBsungIHrNJm6gzwc1r1zRpMZDH55%2fQ"}}],"template_id":"d-1201e63adfa04976ba9fc17212172fe9"} BadRequest Server: nginx Date: Mon, 23 Sep 2019 18:06:50 GMT Connection: keep-alive Access-Control-Allow-Origin: https://sendgrid.api-docs.io Access-Control-Allow-Methods: POST Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl Access-Control-Max-Age: 600 X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html

Can anyone help me please?

Upvotes: 3

Views: 1016

Answers (1)

Simone Spagna
Simone Spagna

Reputation: 636

I solved the problem. When specifying the template ID the substitutions must be passed with the dynamicTemplateData and not with the substituctions.

Here is an example of use provided by Sendgrid at https://github.com/sendgrid/sendgrid-csharp/blob/master/USE_CASES.md#with-mail-helper-class :

using Newtonsoft.Json;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;
using System;

namespace Example
{
  internal class Example
  {
    private static void Main()
    {
        Execute().Wait();
    }

    static async Task Execute()
    {
        var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY");
        var client = new SendGridClient(apiKey);
        var msg = new SendGridMessage();
        msg.SetFrom(new EmailAddress("[email protected]", "Example User"));
        msg.AddTo(new EmailAddress("[email protected]", "Example User"));
        msg.SetTemplateId("d-d42b0eea09964d1ab957c18986c01828");

        var dynamicTemplateData = new ExampleTemplateData
        {
            Subject = "Hi!",
            Name = "Example User",
            Location = new Location
            {
                City = "Birmingham",
                Country = "United Kingdom"
            }
        };

        msg.SetTemplateData(dynamicTemplateData);
        var response = await client.SendEmailAsync(msg);
        Console.WriteLine(response.StatusCode);
        Console.WriteLine(response.Headers.ToString());
        Console.WriteLine("\n\nPress any key to exit.");
        Console.ReadLine();
    }

    private class ExampleTemplateData
    {
        [JsonProperty("subject")]
        public string Subject { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("location")]
        public Location Location { get; set; }
    }

    private class Location
    {
        [JsonProperty("city")]
        public string City { get; set; }

        [JsonProperty("country")]
        public string Country { get; set; }
    }
  }
}

In the template, for example, subject you have to refer with {{subject}}.

Hope this help.

Upvotes: 2

Related Questions