1

我正在尝试发送带有附件的电子邮件。异常:“发送电子邮件失败”内部异常:“无法访问已关闭的流”

MailMessage mm1 = new MailMessage();
mm1.IsBodyHtml = true;
mm1.Body = "Body for person to approve";
mm1.Subject = "Home Owner's Insurance Policy";
mm1.From = new MailAddress("insurance@email.com", "ReplyName");
mm1.ReplyTo = new MailAddress("insurance@email.com");
mm1.To.Add("ross.kriel@email.co.za");

foreach (NewBusinessData item in lData)
{

    MailMessage mm = new MailMessage();
    mm.IsBodyHtml = true;
    mm.Body = HTMLBody;
    mm.Subject = "Home Owner's Insurance Policy";
    mm.From = new MailAddress("insurance@email.com","ReplyName");
    mm.ReplyTo = new MailAddress("insurance@email.com");

   byte[] thisAttachment;
   thisAttachment = Common.Attach(Settings.Default.NewBusinessCSFDataFileWriterPath + item.PolicyNumber + "_" + item.MortgageLoanAccountNumber + ".pdf");

    Stream ClientPDF = new MemoryStream(thisAttachment);

    Attachment attStaticPDF = new Attachment(StaticPDF, "Home Owner's Insurance Policy.pdf");
    Attachment attClientPDF = new Attachment(ClientPDF, item.PolicyNumber + ".pdf");
    mm.Attachments.Add(attStaticPDF);
    mm.Attachments.Add(attClientPDF);

    Assembly assembly = typeof(SmtpClient).Assembly;
    Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
    using (MemoryStream stream = new MemoryStream())
    {
         ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
         object mailWriter = mailWriterContructor.Invoke(new object[] { stream });
         MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
         sendMethod.Invoke(mm, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);

         Attachment emailAtt = new Attachment(stream, "Home Owner's Insurance Policy.msg");

         mm1.Attachments.Add(emailAtt);                                                    
     }                                                                                                                                                                    
 }
 SmtpClient smtp1 = new SmtpClient();
 smtp1.Host = "HostIP";
 smtp1.Port = 25;
 try
 {
     smtp1.Send(mm1);
 }
 catch (Exception exd)
 {
     Console.WriteLine(exd.ToString());
 }
4

4 回答 4

1

只需将 using 子句包裹在整个事物上。一旦执行了 using 子句中的批处理代码,您的流就会超出范围。

试试这个:

using (MemoryStream stream = new MemoryStream())
    {
         ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
         object mailWriter = mailWriterContructor.Invoke(new object[] { stream });
         MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
         sendMethod.Invoke(mm, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);

         Attachment emailAtt = new Attachment(stream, "Home Owner's Insurance Policy.msg");

         mm1.Attachments.Add(emailAtt);                                                                                                                                                                                                                       
 SmtpClient smtp1 = new SmtpClient();
 smtp1.Host = "HostIP";
 smtp1.Port = 25;
 try
     smtp1.Send(mm1);
} // Ending using Clause

或者实际上不要在这里使用 Using 子句,因为这里不需要它。

于 2013-09-19T13:41:00.210 回答
1

因此,归根结底,是传输编码导致了问题。将其指定为八位并确保附件也具有正确的媒体类型解决了该问题。

MailMessage mm1 = new MailMessage();
mm1.IsBodyHtml = true;
mm1.Body = ReportMsgBody;
mm1.Subject = "Home Owner's Insurance Policy Proofs: " + lData.Select(x => x.FileName).First();
mm1.From = new MailAddress("insurance@email.com", "FromName");
mm1.ReplyTo = new MailAddress("insurance@email.com");
mm1.To.Add(receiver.EmailAddress);

foreach (NewBusinessData item in lData)
{
    MailMessage mm = new MailMessage();
    mm.IsBodyHtml = true;
    mm.Body = HTMLBody;
    mm.Subject = "Home Owner's Insurance Policy";
    mm.From = new MailAddress("insurance@email.com", "FromName");
    mm.ReplyTo = new MailAddress("insurance@email.com");
    mm.To.Add(item.EmailAddress);

    byte[] thisAttachment;
    thisAttachment = Common.Attach(Settings.Default.FileWriterPath + item.PolicyNumber + "_" + item.MortgageLoanAccountNumber + ".pdf");
    Stream ClientPDF = new MemoryStream(thisAttachment);
    Attachment attClientPDF = new Attachment(ClientPDF, item.Pr + ".pdf", "application/pdf");
    mm.Attachments.Add(attClientPDF);

    byte[] thisAttachment2;
    thisAttachment2 = Common.Attach(Settings.Default.StaticAttatchmentPath + "Home Owner's Insurance Policy.pdf");
    Stream StaticPDF = new MemoryStream(thisAttachment2);
    Attachment attStaticPDF = new Attachment(StaticPDF, "Home Owner's Insurance Policy.pdf", "application/pdf");
    mm.Attachments.Add(attStaticPDF);

    Assembly assembly = typeof(SmtpClient).Assembly;
    Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
    MemoryStream stream = new MemoryStream();

    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
    object mailWriter = mailWriterContructor.Invoke(new object[] { stream });
    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
    sendMethod.Invoke(mm, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);

    stream.Seek(0, SeekOrigin.Begin);
    Attachment emailAtt = new Attachment(stream, "Home Owner's Insurance Policy", "message/rfc822");
    emailAtt.TransferEncoding = System.Net.Mime.TransferEncoding.EightBit;
    mm1.Attachments.Add(emailAtt);
}
于 2013-09-21T13:52:19.070 回答
0

一旦您离开“使用”范围,流就会关闭。发送后不要使用但关闭流

 try
 {
   smtp1.Send(mm1);
   stream.Close();
 }
 catch (Exception exd)
 {
   Console.WriteLine(exd.ToString());
 }
于 2013-09-19T13:31:09.020 回答
0

由于使用,您正在丢失 MemoryStream。您不必在此处使用 using 。

using (MemoryStream stream = new MemoryStream())
{

采用:

MemoryStream stream = new MemoryStream()

不需要使用,因为没有非托管句柄绑定到 memoryStream(如 FileStream)

如果您仍想使用 using/dispose 方法。您可以将它们添加到列表并在最后进行清理。

于 2013-09-19T13:33:22.253 回答