将保存在磁盘上的eml文件发送

12

我正在使用这里提到的方法创建 eml 文件并将它们保存到目录中。 我想知道如何发送这些 eml 文件? 我尝试使用 SMTPClient 类的对象,但它需要 MailMessage 对象作为参数,我找不到一种方法来使用已保存的 eml 文件创建 MailMessage 类型的对象。

7个回答

8
正确加载EML文件并不像看起来那么简单。你可以在几天内编写一个能够在95%的情况下正常工作的实现。剩下的5%至少需要几个月时间;-)。我知道,因为我曾经参与过其中一个的开发。
考虑以下困难:
- Unicode邮件 - 从右到左的语言 - 纠正由流行的邮件客户端和服务器中已知错误引起的格式不正确的EML文件 - 处理S/MIME(加密和签名电子邮件消息) - 正确处理附件的多种编码方法 - 处理嵌入到HTML邮件中的内联图像和样式表 - 确保它正确解析Mike Crispin(Mime和IMAP RFC的合著者)的MIME torture message消息 - 确保畸形消息不会导致缓冲区溢出或其他应用程序崩溃 - 处理分层消息(带有附加消息的消息) - 确保它正确处理非常大的电子邮件

这样的解析器需要经过多年的发展和不断的用户反馈才能成熟。目前.NET Framework中没有这样的解析器。在它改变之前,我建议从已知供应商那里获取第三方MIME解析器。

以下代码使用我们的Rebex Secure Mail组件,但我相信其他供应商的组件也可以轻松复制类似的任务。

该代码基于Mail Message教程

// create an instance of MailMessage 
MailMessage message = new MailMessage();

// load the message from a local disk file 
message.Load("c:\\message.eml");

// send message
Smtp.Send(message, "smtp.example.org");

1
嗨,马丁,你有没有尝试过这段代码 message.Load()?这个方法不存在。请先尝试您的代码,然后再发布。 - user652961
2
@Vikrant,代码运行得非常好。它使用的是Rebex.Mail.MailMessage类,自版本1.0以来就有Load方法。这在代码上面的帖子中已经提到了。也许你的意思是System.Net.Mail.MailMessage没有Load方法?我知道这一点-这正是我的答案使用不同类的确切原因。 - Martin Vobr

6
使用EMLReader来获取.eml文件中的数据。它包含了创建MailMessage对象所需的所有数据,如发件人、收件人、主题、正文等等。
FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite);
EMLReader reader = new EMLReader(fs);
fs.Close();

MailMessage message = new System.Net.Mail.MailMessage(reader.From, reader.To, reader.Subject, reader.Body);

2
提供的代码无法处理备选视图或附件。 相关文章指定其已过时,并链接到另一篇文章(http://www.codeproject.com/KB/office/EML_ReaderEx.aspx),该文章更好地处理了备选视图和附件,但仍存在一些问题(BCC 似乎被错误地还原为“to”收件人)。 - iammichael
2
是的,我知道。只是想帮助其他遇到同样问题并试图寻找解决方案的人(包括我自己)。另请参阅相关问题:https://dev59.com/CnNA5IYBdhLWcg3wgeEd - iammichael

3
如果您使用的是Microsoft平台且已经有Exchange服务器,那么有另一种解决方案比这里提出的所有其他方案都要简单得多。
每个Exchange服务器都已经默认配置了一个拾取目录。默认情况下,它是`%ExchangeInstallPath%TransportRoles\Pickup`。
您只需将`.eml`文件复制到该目录中,Exchange会自动发送电子邮件。
阅读此 TechNet 文章以获取更多信息:
接收目录和重放目录

2

正如其他人所展示的,EML并不是序列化邮件消息的好方法。您最好将邮件保存为另一种格式。虽然.Net框架中有几个序列化引擎可以序列化任何对象,但您也可以考虑仅在自己设计的Xml文件中保存邮件的组件,例如地址、正文、以base64形式附加的文件。

以下是一个示例,可帮助您入门:

    <?xml version="1.0" encoding="utf-8"?>
    <mail>
      <to display="Thomas Edison" address="tedison@domain.com" />
      <body>
        Hi Thomas,
        How are you doing?
        Bye
      </body>
      <attachment name="MaryLamb.wav">
        cmF0aWUgYWFuIGluIFBERi1mb3JtYWF0LiBEZSBmYWN0dXVyIGlzIGVlbiBvZmZpY2ll
        ZWwgZ2VzaWduZWVyZA0KZG9jdW1lbnQgdmFuIEV1cm9maW5zIE9tZWdhbSBCVi4gRGUg
        c2lnbmF0dXJlIGt1bnQgdSB2ZXJpZmnDq3Jlbi4NCg0KVm9vciBoZXQgdmVyaWZpw6ty
        ...
      </attachment>
    </mail>

另一个优点是,与创建EML不同,您无需使用smtpClient来构建邮件文件。

在C#中,创建和解析XML非常容易。

如果长期归档是目标,您没有说明保存EML的原理。在这种情况下,XML可能具有优势。


1
你可以使用Windows Server内置的SMTP服务器来完成此操作,与之前使用Exchange的方式相同。
将.eml文件放入“C:\ inetpub \ mailroot \ Pickup”中,原始消息将被发送(本地或远程)。
您只需在顶部插入一行即可转发消息:
To: email@address.com

如果需要,您可以进一步操纵邮件头。


1

做我所做的...放弃吧。

构建MailMessage对象似乎是我的焦点,我在这里也有类似的问题未解决... 当我已经将电子邮件作为字符串时,如何发送电子邮件?

从我所见,最简单的方法是使用原始套接字将整个.eml文件内容转储到邮件服务器上,并让邮件服务器通过使用其引擎解析电子邮件来找出难点,例如发件人、收件人主题等。

唯一的问题是...RFC 821...非常繁琐,我正在尝试找出一种干净的方法来快速读取已经在邮箱中的邮件。

编辑:

我找到了一个干净的解决方案,并在我的帖子中介绍了它:)

当我已经将电子邮件作为字符串时,如何发送电子邮件?


0

记录一下:

在Nuget Packager控制台中输入:

Install-Package LumiSoft.Net.dll

然后在你的代码中:

using (FileStream fs = new FileStream( cacheFileName, FileMode.Open, FileAccess.Read )) 
using (LumiSoft.Net.SMTP.Client.SMTP_Client client = 
   new LumiSoft.Net.SMTP.Client.SMTP_Client())
{
    client.SendMessage( fs );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接