无法在多封电子邮件中重复使用电子邮件附件

Posted

技术标签:

【中文标题】无法在多封电子邮件中重复使用电子邮件附件【英文标题】:Cannot reuse email attachment in multiple emails 【发布时间】:2013-02-14 10:57:49 【问题描述】:

我目前在 MVC3 中提供一个表单供用户填写一些字段并附加一个文件。提交时,我将发布的信息(带附件)发送两次......一次作为收据发送给发帖人,第二次发送给另一封目标电子邮件。

我遇到的问题是第一封电子邮件使用正确的附件成功发送。第二封电子邮件会发送一个大小为 0 的附件。似乎从文件上传制作附件对象后,我无法再次重复使用它。使用调试器我可以看到文件上传对象仍在内存中,但它的 ContentLength 变为 0。

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

public static void SendDummyEmail1()

    using (var mailMessage = new MailMessage("from@email.com", "to@email.com"))
    
        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://***.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();

【问题讨论】:

您已经首次将文件发布到服务器。所以下次请求中没有文件。 关注此链接***.com/questions/12356817/… 【参考方案1】:

我想在你的情况下_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), ...

【讨论】:

我的想法正是 Dima,但它没有用。两封电子邮件都带有一个空的附件文件。 我在回答中有更新代码,您的解决方案看起来相似吗?【参考方案2】:

使用内存流作为实例变量,而不是 _fileUpload。 然后将其克隆到每封电子邮件的新蒸汽中(因此不要有多个消费者)。请记住在写入后重置流,以便从头开始读取附件

【讨论】:

【参考方案3】:

将上传的文件存储在服务器上,并在附件中使用文件路径。

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

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

【讨论】:

这并不能解释上述行为。将文件以唯一名称保存在服务器上并在发送后清理也太麻烦了。

以上是关于无法在多封电子邮件中重复使用电子邮件附件的主要内容,如果未能解决你的问题,请参考以下文章

如何一次发送多封电子邮件,每个电子邮件都带有一个 xlsx 文件附件?

用分号正则表达式分隔的多封电子邮件[重复]

保存电子邮件附件时出现运行时错误 '91

在 Python 中发送带有多个附件的电子邮件

在 VBA 中引用查询以发送多封电子邮件

在使用 Excel VBA 发送的电子邮件中内联附加图像