System.Net.Mail 创建无效的电子邮件和 eml 文件?在主机名中插入额外的点

Posted

技术标签:

【中文标题】System.Net.Mail 创建无效的电子邮件和 eml 文件?在主机名中插入额外的点【英文标题】:System.Net.Mail creating invalid emails and eml files? Inserting extra dots in host names 【发布时间】:2011-09-29 22:43:50 【问题描述】:

如果该点出现在 MIME 编码行的开头(例如 test.com 有时显示为 test..com),则 .NET 的 SmtpClient 似乎正在创建在主机名中带有一个额外点的电子邮件。示例代码:

[TestMethod]
public void TestEmailIssue()

    var mail = new System.Net.Mail.MailMessage();
    var smtpClient = new System.Net.Mail.SmtpClient();

    mail.To.Add("Test@test.com");
    mail.Subject = "Test";
    mail.From = new System.Net.Mail.MailAddress("test@test.com");
    mail.Body = "Hello this is  a short test of the issue:"
             +" <a href='https://test.com/'>https://test.com/</a>: ";

    smtpClient.PickupDirectoryLocation = "C:\\temp\\";
    smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.SpecifiedPickupDirectory;
    smtpClient.Send(mail);

这将创建一个如下所示的 .eml 文件:

X-Sender:test@test.com

X-接收者:Test@test.com

MIME 版本:1.0

来自:test@test.com

收件人:Test@test.com

日期:2011 年 7 月 6 日 15:55:28 -0400

主题:测试

内容类型:文本/纯文本; charset=us-ascii

Content-Transfer-Encoding:quoted-printable

您好,这是对该问题的简短测试:https://test=

..com/'>https://test.com/:=20

发送文件或在 Outlook(或任何其他程序)中打开文件时,会出现双点(即 test..com)。请注意,如果我删除多余的空格(在“is a”中),test.com 会正确显示,因为点不再出现在行首。

这在尝试发送网站地址时会导致问题,我们接到客户的电话,说他们无法点击我们的链接。

有其他人经历过吗?除了编写我们自己的编码之外,我们如何解决这个问题?

【问题讨论】:

这就是我们的想法!不幸的是,它直到我们向更多客户推出前一周才出现,我希望有一个简单的解决方法。 我一无所知。一个丑陋的解决方法是打开+解析每个输出的文件,查找这些错误并修复它们。哎呀。 这个额外的 '.'发生是有原因的。这是 SmtpClient 和 Smtp 服务器之间的 Wireshark 跟踪中的一行:“354 输入消息,以“.”结尾单独一行”似乎 Smtp 服务器使用它作为消息结束的指示器 是的,这就是我们更改编码的原因。 【参考方案1】:

这实际上是按照RFC 2821(4.5.2 透明度)

在发送一行邮件文本之前,SMTP 客户端会检查该行的第一个字符。如果是句号,则在行首插入一个句号。

.Net 只是将文件存储为“准备传输”模式,这意味着它不必在发送前处理电子邮件,而是可以按原样传输。不幸的是,这种格式显然与 Outlook Express 的 EML 格式并非 100% 相同。您应该能够将编码设置为 UTF-8(或类似的),这将为您启动 Base-64 编码。

mail.BodyEncoding = System.Text.Encoding.UTF8;

【讨论】:

有没有办法读取这些 eml 文件并正确解码此编码? (我想为测试环境创建一个显示所有电子邮件的仪表板) 本机,使用内置的 MS 类?可能不是,存储格式只是 .Net 和 IIS/Exchange 可能同意的内部表示。据我所知,没有官方规范。你绝对可以自己动手,this post 与图书馆一起做了更多的事情。【参考方案2】:

在 .Net 2.0 中

X-Sender: test@test.com
X-Receiver: Test@test.com
MIME-Version: 1.0
From: test@test.com
To: Test@test.com
Date: 6 Jul 2011 21:29:04 +0100
Subject: Test
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

Hello this is  a short test of the issue: <a href=3D'https://test.com/'>https://test.com/</a>:=

看起来它以每行特定字符长度包装文本。我隐约记得 .Net 2.0 中存在一个问题,默认情况下它不会这样做,这可能会导致垃圾邮件过滤器出现问题。

事实上,增加消息的大小会在 .Net 4.0 中得到以下结果:

X-Sender: test@test.com
X-Receiver: Test@test.com
MIME-Version: 1.0
From: test@test.com
To: Test@test.com
Date: 6 Jul 2011 21:34:21 +0100
Subject: Test
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

Hello this is  a short test of the sssssssssssssssssissue: <a hre=
f=3D'https://test.com/'>https://test.com/</a>:=20

看起来像一个错误。

解决方法可能是将 BodyEncoding 更改为 ASCII 以外的内容。

【讨论】:

+1 用于比较 .Net 2.0 和 .Net 4.0 以识别问题【参考方案3】:

查看 .NET 4 源代码,您所遇到的可能与 MailWriter.WriteAndFold 方法有关。 MailWriter 类中还有

static int writerDefaultLineLength = 76

变量,表示每行的字符数。也许是因为你删除了一个额外的空格字符,它开始工作了。

【讨论】:

以上是关于System.Net.Mail 创建无效的电子邮件和 eml 文件?在主机名中插入额外的点的主要内容,如果未能解决你的问题,请参考以下文章

将 System.Net.Mail.MailMessage 替换为手动创建的消息并发送

.NET 发送电子邮件的最佳方法(System.Net.Mail 有问题)

使用 Gmail SMTP 和 System.Net.Mail 发送电子邮件 [重复]

通过 gmail 使用 System.Net.Mail 发送电子邮件

如何使用 System.Net.Mail 设置退回地址?

C#使用 System.Net.Mail发送邮件功能