Прикрепите файл из MemoryStream к MailMessage в С#
Я пишу программу для прикрепления файла к электронной почте. В настоящее время я сохраняю файл с помощью FileStream
на диск, а затем я использую
System.Net.Mail.MailMessage.Attachments.Add(
new System.Net.Mail.Attachment("file name"));
Я не хочу хранить файл на диске, я хочу сохранить файл в памяти и из потока памяти передать это на Attachment
.
Ответы
Ответ 1
Вот пример кода.
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();
ms.Position = 0;
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";
// I guess you know how to send email with an attachment
// after sending email
ms.Close();
Изменить 1
Вы можете указать другие типы файлов с помощью System.Net.Mime.MimeTypeNames, например System.Net.Mime.MediaTypeNames.Application.Pdf
На основе Mime Type вам необходимо указать правильное расширение в FileName, например "myFile.pdf"
Ответ 2
Немного поздней записи - но, надеюсь, все еще полезно кому-то там: -
Здесь приведен упрощенный фрагмент для отправки строки в памяти в виде вложения электронной почты (CSV файл в этом конкретном случае).
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream)) // using UTF-8 encoding by default
using (var mailClient = new SmtpClient("localhost", 25))
using (var message = new MailMessage("[email protected]", "[email protected]", "Just testing", "See attachment..."))
{
writer.WriteLine("Comma,Seperated,Values,...");
writer.Flush();
stream.Position = 0; // read from the start of what was written
message.Attachments.Add(new Attachment(stream, "filename.csv", "text/csv"));
mailClient.Send(message);
}
StreamWriter и базовый поток не должны удаляться до тех пор, пока сообщение не будет отправлено (чтобы избежать ObjectDisposedException: Cannot access a closed Stream
).
Ответ 3
Поскольку я нигде не мог найти подтверждение об этом, я протестировал, если утилизация MailMessage и/или объекта Attachment будет утилизировать поток, загруженный в них, как я ожидал.
Как показано в следующем тесте, при размещении MailMessage все потоки, используемые для создания вложений, также будут удалены. Таким образом, пока вы распоряжаетесь MailMessage, потоки, которые входили в его создание, не нуждаются в обработке, выходящей за рамки этого.
MailMessage mail = new MailMessage();
//Create a MemoryStream from a file for this test
MemoryStream ms = new MemoryStream(File.ReadAllBytes(@"C:\temp\test.gif"));
mail.Attachments.Add(new System.Net.Mail.Attachment(ms, "test.gif"));
if (mail.Attachments[0].ContentStream == ms) Console.WriteLine("Streams are referencing the same resource");
Console.WriteLine("Stream length: " + mail.Attachments[0].ContentStream.Length);
//Dispose the mail as you should after sending the email
mail.Dispose();
//--Or you can dispose the attachment itself
//mm.Attachments[0].Dispose();
Console.WriteLine("This will throw a 'Cannot access a closed Stream.' exception: " + ms.Length);
Ответ 4
Если вы действительно хотите добавить .pdf, я посчитал необходимым установить позицию потока памяти в ноль.
var memStream = new MemoryStream(yourPdfByteArray);
memStream.Position = 0;
var contentType = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf);
var reportAttachment = new Attachment(memStream, contentType);
reportAttachment.ContentDisposition.FileName = "yourFileName.pdf";
mailMessage.Attachments.Add(reportAttachment);
Ответ 5
Если все, что вы делаете, это привязка строки, вы можете сделать это всего за две строки:
mail.Attachments.Add(Attachment.CreateAttachmentFromString("1,2,3", "text/csv");
mail.Attachments.Last().ContentDisposition.FileName = "filename.csv";
Мне не удалось заставить мою работу работать с нашим почтовым сервером с StreamWriter.
Я думаю, может быть, потому, что с StreamWriter вам не хватает информации о свойствах файла, и, возможно, нашему серверу не понравилось то, что не было.
С Attachment.CreateAttachmentFromString() он создал все, что мне нужно, и отлично работает!
В противном случае я предлагаю взять файл, который находится в памяти, и открыть его с помощью MemoryStream (byte []) и пропустить StreamWriter все вместе.
Ответ 6
Я приземлился на этот вопрос, потому что мне нужно было прикрепить файл Excel, который я генерирую с помощью кода, и доступен как MemoryStream
. Я мог бы прикрепить его к почтовому сообщению, но он был отправлен как 64-битный файл вместо ~ 6 КБ, как это было предусмотрено. Итак, решение, которое сработало для меня, было следующим:
MailMessage mailMessage = new MailMessage();
Attachment attachment = new Attachment(myMemorySteam, new ContentType(MediaTypeNames.Application.Octet));
attachment.ContentDisposition.FileName = "myFile.xlsx";
attachment.ContentDisposition.Size = attachment.Length;
mailMessage.Attachments.Add(attachment);
Установка значения attachment.ContentDisposition.Size
позволяет мне отправлять сообщения с правильным размером вложения.
Ответ 7
используйте ДРУГОЙ ОТКРЫТЫЙ memystream:
пример для lauch pdf и отправьте pdf в MVC4 С# Controller
public void ToPdf(string uco, int idAudit)
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("content-disposition", "attachment;filename= Document.pdf");
Response.Buffer = true;
Response.Clear();
//get the memorystream pdf
var bytes = new MisAuditoriasLogic().ToPdf(uco, idAudit).ToArray();
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.OutputStream.Flush();
}
public ActionResult ToMail(string uco, string filter, int? page, int idAudit, int? full)
{
//get the memorystream pdf
var bytes = new MisAuditoriasLogic().ToPdf(uco, idAudit).ToArray();
using (var stream = new MemoryStream(bytes))
using (var mailClient = new SmtpClient("**YOUR SERVER**", 25))
using (var message = new MailMessage("**SENDER**", "**RECEIVER**", "Just testing", "See attachment..."))
{
stream.Position = 0;
Attachment attach = new Attachment(stream, new System.Net.Mime.ContentType("application/pdf"));
attach.ContentDisposition.FileName = "test.pdf";
message.Attachments.Add(attach);
mailClient.Send(message);
}
ViewBag.errMsg = "Documento enviado.";
return Index(uco, filter, page, idAudit, full);
}
Ответ 8
Я думаю, что этот код поможет вам:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Net.Mail;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
MailAddress SendFrom = new MailAddress(txtFrom.Text);
MailAddress SendTo = new MailAddress(txtTo.Text);
MailMessage MyMessage = new MailMessage(SendFrom, SendTo);
MyMessage.Subject = txtSubject.Text;
MyMessage.Body = txtBody.Text;
Attachment attachFile = new Attachment(txtAttachmentPath.Text);
MyMessage.Attachments.Add(attachFile);
SmtpClient emailClient = new SmtpClient(txtSMTPServer.Text);
emailClient.Send(MyMessage);
litStatus.Text = "Message Sent";
}
catch (Exception ex)
{
litStatus.Text = ex.ToString();
}
}
}