5

我正在使用 .NETSmtpClient发送主题可能包含 ASCII 范围之外的字符的电子邮件。RFC 2047定义了电子邮件文本在包含特殊字符时应如何编码。以下是电子邮件标题中的主题示例:

Subject: Votre enregistrement numéro 123

在编码为 ISO-8859-1 之后,这应该变成:

Subject: =?iso-8859-1?Q?Votre=20enregistrement=20num=E9ro=20123?=

其中所有特殊字符,包括?, =(和其他字符)和空格,都使用=xx转义序列进行编码。

但是,当我查看SmtpClient生成的内容时,我发现它没有转义空格,这意味着邮件客户端收到了这个标头:

Subject: =?iso-8859-1?Q?Votre enregistrement num=E9ro 123?=

这意味着编码在(我的阅读)RFC 2047 方面被破坏了。一些电子邮件客户端对这种不正确的编码非常满意(实际上,其中大多数,包括 Outlook 和 gmail),但有一个(wanadoo.fr)以原始格式显示标题。这不是用户应该看到的:-(

此问题是否有任何已知的解决方法?

注意: .NET 4.0 实现SmtpClient按预期对主题进行编码,产生此输出,这是正确的:

Subject: =?Windows-1252?Q?Votre_enregistrement_num=E9ro_123?=

4

2 回答 2

3

问题是 SMTP 发件人使用了一个通用的引用打印编码器,它对标头的特殊模式一无所知,所以我怀疑不会有简单的解决方法。

我要做的是检查是否有任何非 ASCII 字符,这样主题就会被编码,如果有,用下划线 (ASCII 95) 替换任何空格。这应该有效,因为下划线字符应该被邮件阅读器解释为空格,但不应该被天真的编码器编码。也许这段代码会起作用:

string FixSubject(string subject)
{
    foreach (char ch in subject)
        if (ch > '\x007f')
            return subject.Replace(" ", "_");
    return subject;
}

另一种可能性是将电子邮件的编码设置为 Unicode 或 UTF-8,因为这似乎会触发标头的 Base64 编码而不是引用打印。使用不同的编码器应该完全避免这个错误。

于 2010-03-16T04:44:21.503 回答
1

这已在 .NET 4.0 实现中得到修复SmtpClient。它按预期对主题进行编码,产生以下输出,这是正确的:

Subject: =?Windows-1252?Q?Votre_enregistrement_num=E9ro_123?=

于 2012-04-11T05:28:19.643 回答