2 years ago

#265539

test-img

Maxime Rossini

Force System.Net.Mail.SmtpClient to encode the Subject header using Base64

We are using .NET Core 3.1's default SMTP client to send an email, like this:

private async Task SendMail(string from, string to, string subject, string body)
{
    var message = new MailMessage();

    message.From = new MailAddress(from);
    var toAddress = new MailAddress(to);
    message.To.Add(toAddress);

    message.Subject = subject;
    message.SubjectEncoding = Encoding.UTF8;
    message.Body = body;
    message.BodyEncoding = Encoding.UTF8;
    message.IsBodyHtml = false;

    using var smtp = new SmtpClient();
    smtp.Host = SMTP_HOST;
    smtp.Port = SMTP_PORT;
    smtp.EnableSsl = false;
    smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
    smtp.DeliveryFormat = SmtpDeliveryFormat.International;
    smtp.UseDefaultCredentials = false;
    smtp.Credentials = new NetworkCredential(SMTP_USER, SMTP_PASSWORD);

    await smtp.SendMailAsync(message);
}

Then we call the method like this:

await this.SendMail(
    from: "noreply@ourdomain.com",
    to: "recipient@example.com",
    subject: "Caractères accentués",
    body: "dummy"
);

When using a network analyzer to check how the Subject header is encoded, we are observing the following:

  • When the client connects to a MTA that supports SMTPUTF8, the Subject header is encoded using UTF8: Subject: Caractères accentués.
  • When the client connects to a MTA that does not support SMTPUTF8, the Subject header is encoded in Base64 then in US-ASCII: Subject: =?utf-8?B?Q2FyYWN0w6hyZXMgYWNjZW50dcOpcw==?=.
  • If we switch from SmtpDeliveryFormat.International to SmtpDeliveryFormat.SevenBits, the Subject header is always encoded in Base64 then in US-ASCII (or maybe quoted-url then US-ASCII).

This is all standard and excpected behaviour.

We are using a third party email service as a SMTP relay, which supports SMTPUTF8 itself. But their service has a bug and fails to detect the lack of SMTPUTF8 support on recipient's side, resulting in email Subjects being improperly displayed in our clients mailboxes when they contain non-ASCII characters. They send the Subject with the same encoding we used with their MTA, which in our case is UTF8, because we need SmtpDeliveryFormat.International (for compatibility with non-ASCII email addresses).

The issue disappears when we encode the Subject header using Base64, so we would like to do that as a workaround until our provider fixes the issue on their side. Using smtp.DeliveryFormat = SmtpDeliveryFormat.SevenBits achieves this, but it also prevents us from using non-ASCII characters in email addresses, which is an even bigger problem than the Subject encoding issue. So we can't do that.

Is there a way to force the .NET client to use Base64 encoding for the Subject header while also using SmtpDeliveryFormat.International, even when the SMTP relay supports SMTPUTF8? I tried to do this:

message.Subject = $"=?utf-8?B?{Convert.ToBase64String(Encoding.UTF8.GetBytes(subject))}?=";

But the subject header is not passed through, it is decoded by the SmtpClient then UTF8-encoded as Caractères accentués, so it doesn't change anything.

.net-core

character-encoding

smtp

smtpclient

system.net.mail

0 Answers

Your Answer

Accepted video resources