Прикрепить файл с потоке MemoryStream, чтобы получить помощь в C#
Я пишу программу, чтобы прикрепить файл к электронной почте. В настоящее время я сохраняю файл с помощью FileStream
на диск, а затем я использую
System.Net.Mail.MailMessage.Attachments.Add(
new System.Net.Mail.Attachment("file name"));
Я не хочу хранить файл на диске, я хочу хранить файл в памяти и из потока памяти передать это в Attachment
.
8 ответов:
вот пример кода.
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
можно указать другие типы файлов системы.Чистая.Миме.MimeTypeNames как
System.Net.Mime.MediaTypeNames.Application.Pdf
на основе Тип Mime нужно указать правильное расширение в имени файла, например
"myFile.pdf"
немного поздняя запись - но, надеюсь, все еще полезно для кого-то там: -
вот упрощенный фрагмент для отправки строки в памяти в качестве вложения электронной почты (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("me@example.com", "you@example.com", "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
).
поскольку я не мог найти подтверждения этого нигде, я проверил, будет ли утилизация MailMessage и/или объекта вложения утилизировать поток, загруженный в них, как я ожидал.
это появляется со следующим тестом, что при удалении 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);
Если вы действительно хотите добавить a .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);
Если все, что вы делаете, это прикрепление строки, вы можете сделать это всего за 2 строки:
mail.Attachments.Add(Attachment.CreateAttachmentFromString("1,2,3", "text/csv"); mail.Attachments.Last().ContentDisposition.FileName = "filename.csv";
Я не смог заставить мой работать с помощью нашего почтового сервера с StreamWriter.
Я думаю, может быть, потому что с StreamWriter вам не хватает много информации о свойствах файлов, и, возможно, нашему серверу не понравилось то, что отсутствовало.
с привязанностью.CreateAttachmentFromString () он создал все, что мне нужно, и отлично работает!в противном случае, я бы предложил взять ваш файл то есть в памяти и открывая его с помощью MemoryStream(byte[]), и пропуская StreamWriter все вместе.
Я приземлился на этот вопрос, потому что мне нужно было прикрепить файл Excel, который я создаю с помощью кода и доступен как
MemoryStream
. Я мог бы прикрепить его к почтовому сообщению, но он был отправлен как файл 64Bytes вместо ~6KB, как это было задумано. Итак, решение, которое сработало для меня, было следующим: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
позвольте мне отправлять сообщения с правильным размером вложения.
использовать другие открытые memorystream:
пример для lauch pdf и отправить pdf в MVC4 C# 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); }
Я думаю, что этот код поможет вам:
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(); } } }