メールにファイルを添付するプログラムを書いています。現在、FileStream
を使用してファイルをディスクに保存し、次に使用しています
System.Net.Mail.MailMessage.Attachments.Add(
new System.Net.Mail.Attachment("file name"));
ファイルをディスクに保存したくありません。ファイルをメモリに保存し、メモリストリームから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();
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.MediaTypeNames.Application.Pdf
のようなSystem.Net.Mime.MimeTypeNamesによって他のファイルタイプを指定できます。
MIMEタイプに基づいて、インスタンス"myFile.pdf"
のFileNameに正しい拡張子を指定する必要があります
少し遅れたエントリ-しかし、うまくいけば、そこにいる誰かにとってはまだ便利です:-
これは、メモリ内の文字列を電子メールの添付ファイル(この場合は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
を避けるため)。
これの確認はどこにも見つからなかったので、MailMessageやAttachmentオブジェクトを破棄すると、予想どおりにロードされたストリームが破棄されるかどうかをテストしました。
次のテストでは、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);
実際に.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では多くのファイルプロパティ情報が欠落しているため、サーバーが欠落しているものを好まなかったためと思われます。
Attachment.CreateAttachmentFromString()を使用すると、必要なものがすべて作成され、うまく機能します。
そうでない場合は、メモリ内のファイルを取得し、MemoryStream(byte [])を使用して開き、StreamWriterをすべてスキップすることをお勧めします。
他のOPENメモリストリームを使用します。
lauch pdfの例とMVC4 C#コントローラーでpdfを送信
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);
}
コードで生成したExcelファイルを添付する必要があり、MemoryStream
として入手できるため、この質問にたどり着きました。メールメッセージに添付することはできましたが、本来の目的である〜6KBではなく64Bytesファイルとして送信されました。だから、私のために働いた解決策はこれでした:
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
の値を設定すると、正しいサイズの添付ファイルでメッセージを送信できます。