Я пытаюсь отправить электронную почту с вложением с помощью С#. Вот мой метод:
public void SendEmail(string from, string to, SmtpClient client)
{
MailMessage mm = new MailMessage(from, to, "Otrzymałeś nowe zamówienie od "+from , "Przesyłam nowe zamówienie na sprzęt");
mm.BodyEncoding = UTF8Encoding.UTF8;
mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
// Adding attachment:
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.StreamWriter writer = new System.IO.StreamWriter(ms);
writer.Write("Hello its my sample file");
writer.Flush();
writer.Dispose();
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
attach.ContentDisposition.FileName = "myFile.txt";
mm.Attachments.Add(attach);
try
{
client.Send(mm);
}
catch(SmtpException e)
{
Console.WriteLine(e.ToString());
}
ms.Close();
}
stacktrace указывает на эту строку:
client.Send(mm);
проблема вызвана этой строкой:
writer.Dispose();
Почему я не могу удалить этот элемент сразу после его использования для записи в MemoryStream
? Этот элемент не используется в дальнейшем в коде.
Вызов Dispose на писателе также Dispose базовый поток. После отправки письма вы должны распоряжаться как писателем, так и потоком. Вы можете добиться этого, обернув свой код двумя операциями.
using(var ms = new System.IO.MemoryStream())
{
using(var writer = new System.IO.StreamWriter(ms))
{
writer.Write("Hello its my sample file");
writer.Flush();
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
attach.ContentDisposition.FileName = "myFile.txt";
mm.Attachments.Add(attach);
try
{
client.Send(mm);
}
catch(SmtpException e)
{
Console.WriteLine(e.ToString());
}
}
}
Используйте использование блока, как это предлагается в комментариях:
//...
using(System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
using(System.IO.StreamWriter writer = new System.IO.StreamWriter(ms))
{
writer.Write("Hello its my sample file");
writer.Flush();
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
attach.ContentDisposition.FileName = "myFile.txt";
mm.Attachments.Add(attach);
client.Send(mm);
}
}
Когда client.Send
пытается отправить его, очевидно, будет прочитано Attachment
которое указывает на MemoryStream
который уже был закрыт StreamWriter
. Вы можете проверить это, ms.CanRead
Он вернет false.
Доступ к закрытому потоку вызовет исключение, что вы переживаете. Чтобы решить это, просто избавьтесь от writer.Dispose()
поскольку нет ничего, чтобы распоряжаться с MemoryStream
или распоряжаться им после завершения вашей работы.