2009-08-12 104 views

回答

102

为了简单起见,我就从Connect item引用的解释:

实际上,你可以配置 SmtpClient发送电子邮件到文件 系统,而不是网络。您可以 做到这一点编程方式使用 下面的代码:

SmtpClient client = new SmtpClient("mysmtphost"); 
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory; 
client.PickupDirectoryLocation = @"C:\somedirectory"; 
client.Send(message); 

你也可以在你的 应用程序配置文件设置此像 这样:

<configuration> 
    <system.net> 
     <mailSettings> 
      <smtp deliveryMethod="SpecifiedPickupDirectory"> 
       <specifiedPickupDirectory pickupDirectoryLocation="C:\somedirectory" /> 
      </smtp> 
     </mailSettings> 
    </system.net> 
</configuration> 

发送电子邮件后,你应该 看到电子邮件文件被添加到您指定的 目录。然后您可以使用批处理模式发送 电子邮件,然后 有单独的进程。

您应该可以使用空构造函数而不是列出的构造函数,因为它不会发送它。

+1

我发现,我还需要添加<网络主机=“...”等,除了瑞恩提供。 – 2011-07-07 20:42:13

+8

有什么方法可以更改输出.eml文件的文件名?我宁愿它看起来不像以下内容:f80f4695-551c-47d7-8879-40ad89707b23.eml谢谢! – buzzzzjay 2011-10-03 19:07:23

+6

尽管是一个旧帖子,我想从@buzzzzjay添加最后一个问题的答案:看看这里:[link](http://www.codeproject.com/Articles/32434/Adding-Save-functionality- to-Microsoft-Net-Mail-Ma) – 2013-01-10 13:22:35

22

下面是将MailMessage转换为包含EML数据的流的扩展方法。 它使用文件系统显然有点破绽,但它起作用。

public static void SaveMailMessage(this MailMessage msg, string filePath) 
{ 
    using (var fs = new FileStream(filePath, FileMode.Create)) 
    { 
     msg.ToEMLStream(fs); 
    } 
} 

/// <summary> 
/// Converts a MailMessage to an EML file stream. 
/// </summary> 
/// <param name="msg"></param> 
/// <returns></returns> 
public static void ToEMLStream(this MailMessage msg, Stream str) 
{ 
    using (var client = new SmtpClient()) 
    { 
     var id = Guid.NewGuid(); 

     var tempFolder = Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name); 

     tempFolder = Path.Combine(tempFolder, "MailMessageToEMLTemp"); 

     // create a temp folder to hold just this .eml file so that we can find it easily. 
     tempFolder = Path.Combine(tempFolder, id.ToString()); 

     if (!Directory.Exists(tempFolder)) 
     { 
      Directory.CreateDirectory(tempFolder); 
     } 

     client.UseDefaultCredentials = true; 
     client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory; 
     client.PickupDirectoryLocation = tempFolder; 
     client.Send(msg); 

     // tempFolder should contain 1 eml file 

     var filePath = Directory.GetFiles(tempFolder).Single(); 

     // stream out the contents 
     using (var fs = new FileStream(filePath, FileMode.Open)) 
     { 
      fs.CopyTo(str); 
     } 

     if (Directory.Exists(tempFolder)) 
     { 
      Directory.Delete(tempFolder, true); 
     } 
    } 
} 

您可以再取这就是返回的流,做你想做的事情,包括保存到另一个位置在磁盘或数据库字段存储,甚至电子邮件作为附件。

+1

Hi Saille ...你的代码工作的很好,是的,它创建了eml或Msg文件,但我无法在MS Outlook中打开它:(需要你的帮助。 – 2014-09-25 08:28:24

+2

.EML文件应该在Outlook中打开,但如果你不能,请尝试将文件扩展名重命名为。MHT,然后在Internet Explorer中打开它。 – saille 2014-10-21 23:12:50

+0

Saille - 是否可以保存没有“发件人”地址,因此可以从打开它的用户发送?干杯。 – 2015-10-06 12:19:56

0

由于某种原因client.send失败(在使用该方法实际发送之后),因此我插入了良好的'ole CDO和ADODB流。在设置.Message值之前,我还必须使用template.eml加载CDO.message。但它的工作。

因为上面一个是C这里是一个VB

MyMessage.From = New Net.Mail.MailAddress(mEmailAddress) 
    MyMessage.To.Add(mToAddress) 
    MyMessage.Subject = mSubject 
    MyMessage.Body = mBody 

    Smtp.Host = "------" 
    Smtp.Port = "2525" 
    Smtp.Credentials = New NetworkCredential(------) 

    Smtp.Send(MyMessage)  ' Actual Send 

    Dim oldCDO As CDO.Message 
    oldCDO = MyLoadEmlFromFile("template.eml") ' just put from, to, subject blank. leave first line blank 
    oldCDO.To = mToAddress 
    oldCDO.From = mEmailAddress 
    oldCDO.Subject = mSubject 
    oldCDO.TextBody = mBody 
    oldCDO.HTMLBody = mBody 
    oldCDO.GetStream.Flush() 
    oldCDO.GetStream.SaveToFile(yourPath)