SmtpClient (.NET) não codifica o cabeçalho de correio em conformidade com a RFC 2047
-
20-09-2019 - |
Pergunta
Estou usando .NET SmtpClient
Para enviar e-mail para onde o sujeito pode conter caracteres fora da faixa ASCII. o RFC 2047 Define como o texto de email deve ser codificado quando contém caracteres especiais. Aqui está um exemplo de assunto em um cabeçalho de e-mail:
Subject: Votre enregistrement numéro 123
Isso deve se tornar, depois de codificar para ISO-8859-1:
Subject: =?iso-8859-1?Q?Votre=20enregistrement=20num=E9ro=20123?=
onde todos os personagens especiais, incluindo ?
, =
(e outros) e espaço em branco, são codificados usando o =xx
sequência de fuga.
No entanto, quando eu olho para o que SmtpClient
Produz, descubro que ele não escapa dos espaços brancos, o que significa que o cliente de email recebe este cabeçalho:
Subject: =?iso-8859-1?Q?Votre enregistrement num=E9ro 123?=
o que significa que a codificação está quebrada em relação a (minha leitura) RFC 2047. Alguns clientes de e-mail estão perfeitamente felizes com essa codificação incorreta (a maioria deles, de fato, incluindo Outlook e Gmail), mas um (wanadoo.fr) Exibe o cabeçalho em seu formato bruto. Não é isso que o usuário deve ver :-(
Existe alguma solução alternativa conhecida para esta questão?
Observação: A implementação .NET 4.0 de SmtpClient
codifica o sujeito como esperado, produzindo essa saída, que está correta:
Subject: =?Windows-1252?Q?Votre_enregistrement_num=E9ro_123?=
Solução
O problema é que o remetente do SMTP usa um codificador genérico de impressão citada que não sabe nada sobre o modo especial para cabeçalhos, então suspeito que não haja uma solução alternativa simples.
O que eu faria é verificar se existem caracteres não-ASCII, de modo que o sujeito será codificado e, se assim, substitua algum espaços por sublinhados (ASCII 95). Isso deve funcionar porque o personagem sublinhado deve ser interpretado como um espaço pelo leitor de correio, mas não deve ser codificado pelo codificador ingênuo. Talvez este código funcione:
string FixSubject(string subject)
{
foreach (char ch in subject)
if (ch > '\x007f')
return subject.Replace(" ", "_");
return subject;
}
Outra possibilidade é definir a codificação do seu email para Unicode ou UTF-8, porque isso parece desencadear a codificação Base64 dos cabeçalhos em vez de impressão citada. O uso de um codificador diferente deve evitar o bug.
Outras dicas
Isso foi corrigido na implementação líquida 4.0 de SmtpClient
. Ele codifica o assunto como esperado, produzindo essa saída, que está correta:
Subject: =?Windows-1252?Q?Votre_enregistrement_num=E9ro_123?=