2013-02-28 151 views
2

我目前在MVC3中为用户填写一些字段并附加文件提供了一个表单。在提交时,我将发布的信息(附件)两次发送到海报作为收据,第二次发送到另一个目标电子邮件。无法在多封电子邮件中重复使用电子邮件附件

我遇到的问题是第一封电子邮件成功发送与正确attachemnt。第二封电子邮件会发送一个大小为0的附件。看起来,在我从文件上传中创建附件对象之后,我无法再重复使用它。使用调试器,我可以看到,文件上传对象仍然在内存中,它的击打的ContentLength变为0

所以在下面的例子中,如果我简化了我的代码如下:

public static void SendDummyEmail1() 
{ 
    using (var mailMessage = new MailMessage("[email protected]", "[email protected]")) 
    { 
     mailMessage.Subject = "Email Subject" 
     mailMessage.Body = Razor.Parse(template, (dynamic)dynamicTokens); 
     mailMessage.IsBodyHtml = true; 

     if (_fileUpload != null && _fileUpload.ContentLength > 0) 
     { 
      var attachment = new Attachment(_fileUpload.InputStream, _fileUpload.FileName, MediaTypeNames.Application.Octet); 
      attachment.ContentDisposition.FileName = Path.GetFileName(_fileUpload.FileName); 
      mailMessage.Attachments.Add(attachment); 
     } 

     SendMail(mailMessage); 
    } 
} 

public static void SendMail(MailMessage message) 
{ 
    var client = new SmtpClient 
    { 
     Host = ConfigurationManager.AppSettings[SmtpHostname], 
     Port = Convert.ToInt32(ConfigurationManager.AppSettings[SmtpPortNumber]), 
     UseDefaultCredentials = true, 
     Credentials = CredentialCache.DefaultNetworkCredentials, 
     DeliveryMethod = SmtpDeliveryMethod.Network, 
     EnableSsl = true, 
    }; 

    // Work around remote certificate validation 
    // Ref: http://stackoverflow.com/questions/777607/the-remote-certificate-is-invalid-according-to-the-validation-procedure-using 
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

    client.Send(message); 
} 

如果我是要连续调用上述方法两次,第一封电子邮件将成功通过。第二个电子邮件会经过,但没有附件,因为的ContentLength变为0

SendDummyEmail1(); 
SendDummyEmail1(); 
+0

您已经将文件首次发布到服务器。所以下次请求时没有文件。 – 2013-02-28 10:55:59

+0

按照此链接http://stackoverflow.com/questions/12356817/can-not-attach-multiple-files-in-the-attachment-of-email-in-c-sharp/27705328#27705328 – 2014-12-30 12:22:21

回答

3

我想_fileUpload.InputStream.CanSeek在你的情况等于false,这意味着你不能再把它(Position = 0)并从它读取。尝试上传的文件流的第一个复制到内存流,然后用它代替初始流,就像这样:

MemoryStream ms = new MemoryStream(); 
_fileUpload.InputStream.CopyTo(ms); 
byte[] data = ms.ToArray(); 
SendDummyEmail1(data); 
SendDummyEmail1(data); 

public static void SendDummyEmail1(byte[] fileContent) 
{ 
... 
var attachment = new Attachment(new MemoryStream(fileContent), ... 
} 
+0

我的想法正是迪马,但它没有奏效。两封电子邮件都发送出一个空的附件文件。 – Hady 2013-02-28 10:44:45

+0

我在回答中有更新代码,您的解决方案看起来类似吗? – Dima 2013-02-28 11:11:06

+0

这不适用于.NET 3.5 ...只是说。 – GenXisT 2013-06-03 15:10:17

0

商店上传到服务器上的文件和附件使用的文件路径。

var attachment = new Attachment(filePath, MediaTypeNames.Application.Octet); 

删除上传的文件,如果需要发送电子邮件后。

+0

这并不解释上述行为。使用唯一的名称保存服务器上的文件并在发送后进行清理也是一件麻烦事。 – Hady 2013-02-28 10:22:59

3

使用内存流为您的实例变量,而不是_fileUpload。 然后克隆它到每个电子邮件的新蒸汽(所以没有多个消费者)。请记住在写入数据流之后重置数据流,以便附件读取从头开始