使用 SmtpClient 时如何保存电子邮件而不是发送?

Posted

技术标签:

【中文标题】使用 SmtpClient 时如何保存电子邮件而不是发送?【英文标题】:How can I save an email instead of sending when using SmtpClient? 【发布时间】:2010-10-08 17:46:49 【问题描述】:

我正在使用 SmtpClient 发送带有附件的电子邮件。 但是对于某个批次,我们需要以某种方式保存 MailMessage 而不是发送它们。 然后我们正在考虑/希望手动将消息上传到用户草稿文件夹。

是否可以保存这些带有完整附件的邮件(我原以为不可能)。或者将消息上传到用户帐户中的文件夹?

如果有人有这方面的经验,我会非常感谢一些帮助或指点。

【问题讨论】:

【参考方案1】:

您可以使用web.config / app.config 文件中的system.net 设置进行配置。

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network">
      <network host="mail.mydomain.com" port="25" />
    </smtp>
    <!-- Use this setting for development
    <smtp deliveryMethod="SpecifiedPickupDirectory">
      <specifiedPickupDirectory pickupDirectoryLocation="C:\Temp" />
    </smtp>
    -->
  </mailSettings>
</system.net>

另外,这里有一个链接,上面有 migrating from System.Web.Mail to System.Net.Mail 的信息。

【讨论】:

【参考方案2】:

在 ASP.NET 中进行测试时,我们将电子邮件保存到一个文件夹中,而不是通过电子邮件服务器发送它们。也许您可以像这样为您的批次更改web.config 设置?

<system.net>
  <mailSettings>
    <smtp deliveryMethod="SpecifiedPickupDirectory">
      <specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\mail\"/>
    </smtp>
  </mailSettings>
</system.net>

其他信息:

MSDN: <specifiedPickupDirectory> Element (Network Settings) Configuring SmtpClient to drop emails in a folder on disk

【讨论】:

谢谢你的款待。 Avram(见下文)还发布了一个有用的链接,讨论了将电子邮件名称从自动生成的 GUID 更改为您自己的值。 我已经尝试过这种方法,但我收到一个错误,即未指定“发件人”地址。有没有办法在 web.config 中为 SpecifiedPickupDirectory 指定这个?当你做网络设置有【参考方案3】:

这会有所帮助 - Adding Save() functionality to Microsoft.Net.Mail.MailMessage 主要思想,对 MailMessage 做一个扩展,通过反射做一个保存方法。

【讨论】:

谢谢,看看我是否也可以在这里添加附件会很有趣。【参考方案4】:

除了其他答案的SpecifiedPickupDirectory 信息外,如果您想确保将电子邮件发送到相对于站点根目录的文件夹 - 在您不知道路径的构建服务器上进行测试时很方便 - 您可以在您的电子邮件发送代码中添加快速检查:

    SmtpClient client = new SmtpClient();
    ...

    // Add "~" support for pickupdirectories.
    if (client.DeliveryMethod == SmtpDeliveryMethod.SpecifiedPickupDirectory && client.PickupDirectoryLocation.StartsWith("~"))
    
        string root = AppDomain.CurrentDomain.BaseDirectory;
        string pickupRoot = client.PickupDirectoryLocation.Replace("~/", root);
        pickupRoot = pickupRoot.Replace("/",@"\");
        client.PickupDirectoryLocation = pickupRoot;
    

您的测试将如下所示(确保您使用 App_Data 以便 IIS 可以写入该文件夹):

    // Arrange - get SitePath from AppDomain.Current.BaseDirectory + ..\
    string pickupPath = Path.Combine(SitePath, "App_Data", "TempSmtp");
    if (!Directory.Exists(pickupPath))
        Directory.CreateDirectory(pickupPath);

    foreach (string file in Directory.GetFiles(pickupPath, "*.eml"))
    
        File.Delete(file);
    

    // Act (send some emails)

    // Assert
    Assert.That(Directory.GetFiles(pickupPath, "*.eml").Count(), Is.EqualTo(1));

【讨论】:

谢谢伙计。这就是我要找的! 好一个。谢谢【参考方案5】:

还需要在某些版本的框架中添加一个错误作为解决方法。所以完成的版本是这样的:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="SpecifiedPickupDirectory">
        <specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\mail\"/>
        <network host="localhost" />
    </smtp>
  </mailSettings>
</system.net>

【讨论】:

以上是关于使用 SmtpClient 时如何保存电子邮件而不是发送?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SmtpClient.SendAsync 发送带有附件的电子邮件?

SmtpClient - 发送到不同的域

使用 SmtpClient 发送邮件时图像中断

smtpclient.send 在尝试通过 Office 365 发送电子邮件时挂起

如何使用 POP3 和 SmtpClient 转发多部分 MIME 电子邮件?

使用第三方与投递文件夹时 SMTPClient 发送限制为 50 封电子邮件