简体   繁体   English

如何使用 System.Net.Mail 向电子邮件添加附件?

[英]How do I add an attachment to an email using System.Net.Mail?

I have an excel document represented as a byte[] and I'm wanting to send it as an attachment in an email.我有一个表示为 byte[] 的 excel 文档,我想将它作为电子邮件中的附件发送。

I'm having a bit of trouble constructing the attachment.我在构建附件时遇到了一些麻烦。

I can create an Attachment which has the following constructors:我可以创建一个具有以下构造函数的附件:

(Stream contentStream, ContentType contentType)
(Stream contentStream, string name)
(Stream contentStream, string name, string mediaType)

My idea at the moment is to create a MemoryStream from the byte[] and pass it to the method which creates the attachment.我目前的想法是从 byte[] 创建一个 MemoryStream 并将其传递给创建附件的方法。

Unfortunately I can't see a way to obtain the intended filename and content type from the MemoryStream and I also can't see how to supply the correct content type.不幸的是,我看不到从 MemoryStream 获取预期文件名和内容类型的方法,也看不到如何提供正确的内容类型。 There are options for plain text, Pdf, Rtf etc but none that I can see that immediately jump out at me as the one I should use for an Excel document.有纯文本、Pdf、Rtf 等选项,但没有一个我能立即跳出来作为我应该用于 Excel 文档的选项。

The closest I can find is MediaTypeNames.Application.Octet which states:我能找到的最接近的是MediaTypeNames.Application.Octet ,它指出:

The Octet member designates that the attachment contains generic binary data. Octet 成员指定附件包含通用二进制数据。

However, even if this is the one to use, unless it can be passed as a property of the Stream then my method for sending emails will only be able to send a byte[] as an Excel document...但是,即使这是要使用的,除非它可以作为 Stream 的属性传递,否则我发送电子邮件的方法只能将 byte[] 作为 Excel 文档发送...

Is there perhaps some other sort of Stream I could use?也许我可以使用其他类型的流? Or will I have to create my own type of Stream that has the details I need.或者我是否必须创建自己类型的 Stream,其中包含我需要的详细信息。

Surely someone out there has done this thing before and surely Microsoft would have thought this through to this level....肯定有人以前做过这件事,而且微软肯定会考虑到这个程度......

Any help would be much appreciated.任何帮助将非常感激。

Update: Please don't vote for any answers that use the constructors that take the filename as a string.更新:请不要投票支持使用将文件名作为字符串的构造函数的任何答案。 I'm really needing help using the ones that take a Stream...I want to avoid having to write the file to disk, email it, and then immediately delete it.我真的需要使用 Stream 的帮助...我想避免将文件写入磁盘,通过电子邮件发送,然后立即将其删除。 Since there is a method that allows me to do that I'd like to use that one if at all possible.由于有一种方法可以让我这样做,如果可能的话,我想使用该方法。

Solution Update解决方案更新

Conrad managed to find what I was looking for!康拉德设法找到了我要找的东西! Thanks heaps man!谢谢堆人!

I'll just document the suggested solution just in case something happens to the content at the supplied link.我只会记录建议的解决方案,以防万一提供的链接中的内容发生问题。

Credit for this solution goes to www.systemnetmail.com此解决方案归功于 www.systemnetmail.com

static void AttachmentFromStream()
{

//create the mail message
MailMessage mail = new MailMessage();

//set the addresses
mail.From = new MailAddress("me@mycompany.com");
mail.To.Add("you@yourcompany.com");

//set the content
mail.Subject = "This is an email";
mail.Body = "this content is in the body";

//Get some binary data
byte[] data = GetData();

//save the data to a memory stream
MemoryStream ms = new MemoryStream(data);

//create the attachment from a stream. Be sure to name the data 
//with a file and 
//media type that is respective of the data
mail.Attachments.Add( new Attachment( ms, "example.txt", "text/plain" ));

SmtpClient smtp = new SmtpClient("127.0.0.1");
smtp.Send(mail);
}

In my case, it just means I'll have to change my method to take the filename and fileformat as strings.就我而言,这只是意味着我必须更改我的方法以将文件名和文件格式作为字符串。 I'll try using the Octet one...but failing that I'll just pass in the official MIME type.我将尝试使用 Octet 一个...但如果失败,我将只传递官方 MIME 类型。

All things considered, this is a pretty obvious solution...but I do appreciate the help in solving it...and the good thing is this solution will be documented for future programmers who have the same problem.考虑到所有因素,这是一个非常明显的解决方案......但我确实很感激解决它的帮助......好消息是这个解决方案将为未来遇到相同问题的程序员记录。

Thanks again everyone for you help!再次感谢大家的帮助!

The attachment constructor does indeed have a constructor that does what you need.附件构造函数确实有一个构造函数可以满足您的需要。 I'm assuming you're using the System.Net.MailMessage class from .NET Framework 2. If so read this link for some sample code of what you need我假设您正在使用 .NET Framework 2 中的 System.Net.MailMessage 类。如果是这样,请阅读此链接以获取您需要的一些示例代码

Since the link from the accepted answer is gone, here it is from the Wayback Machine由于已接受答案链接已消失,因此它来自Wayback Machine

TL;DR: mail.Attachments.Add(new Attachment(contentStream, "yourfilename.txt", "text/plain")); TL; DR: mail.Attachments.Add(new Attachment(contentStream, "yourfilename.txt", "text/plain"));

Full:满的:

static void AttachmentFromStream()
{

    //create the mail message
    MailMessage mail = new MailMessage();

    //set the addresses
    mail.From = new MailAddress("me@mycompany.com");
    mail.To.Add("you@yourcompany.com");

    //set the content
    mail.Subject = "This is an email";
    mail.Body = "this content is in the body";

    //Get some binary data
    byte[] data = GetData();

    //save the data to a memory stream
    MemoryStream ms = new MemoryStream(data);

    //create the attachment from a stream. Be sure to name the data with a file and 
    //media type that is respective of the data
    mail.Attachments.Add(new Attachment(ms, "example.txt", "text/plain"));

    //send the message
    SmtpClient smtp = new SmtpClient("127.0.0.1");
    smtp.Send(mail);
}
static byte[] GetData()
{
    //this method just returns some binary data.
    //it could come from anywhere, such as Sql Server
    string s = "this is some text";
    byte[] data = Encoding.ASCII.GetBytes(s);
    return data;
}

Got this answer from Microsoft docs:从 Microsoft 文档中得到了这个答案:

public static void CreateMessageWithAttachment(string server)
{
    // Specify the file to be attached and sent.
    // This example assumes that a file named Data.xls exists in the
    // current working directory.
    string file = "data.xls";
    // Create a message and set up the recipients.
    MailMessage message = new MailMessage(
        "jane@contoso.com",
        "ben@contoso.com",
        "Quarterly data report.",
        "See the attached spreadsheet.");

    // Create  the file attachment for this email message.
    Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
    // Add time stamp information for the file.
    ContentDisposition disposition = data.ContentDisposition;
    disposition.CreationDate = System.IO.File.GetCreationTime(file);
    disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
    disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
    // Add the file attachment to this email message.
    message.Attachments.Add(data);

    //Send the message.
    SmtpClient client = new SmtpClient(server);
    // Add credentials if the SMTP server requires them.
    client.Credentials = CredentialCache.DefaultNetworkCredentials;

    try
    {
        client.Send(message);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}",
            ex.ToString());
    }
    // Display the values in the ContentDisposition for the attachment.
    ContentDisposition cd = data.ContentDisposition;
    Console.WriteLine("Content disposition");
    Console.WriteLine(cd.ToString());
    Console.WriteLine("File {0}", cd.FileName);
    Console.WriteLine("Size {0}", cd.Size);
    Console.WriteLine("Creation {0}", cd.CreationDate);
    Console.WriteLine("Modification {0}", cd.ModificationDate);
    Console.WriteLine("Read {0}", cd.ReadDate);
    Console.WriteLine("Inline {0}", cd.Inline);
    Console.WriteLine("Parameters: {0}", cd.Parameters.Count);
    foreach (DictionaryEntry d in cd.Parameters)
    {
        Console.WriteLine("{0} = {1}", d.Key, d.Value);
    }
    data.Dispose();
}

--------------- I guess im wrong, this is if you have a file you want to attach --------------- --------------- 我猜我错了,这是如果您有要附加的文件 ---------------

it looks like there is an example of sending mail with an attachment here:看起来这里有一个发送带有附件的邮件的例子:

http://www.aspnettutorials.com/tutorials/email/email-attach-aspnet2-csharp.aspx http://www.aspnettutorials.com/tutorials/email/email-attach-aspnet2-csharp.aspx

I hope this is what you're looking for.我希望这就是你要找的。

The name parameter in the Attachment constructor is the name that will be displayed for the attachment in the recipient's email. Attachment 构造函数中的 name 参数是将在收件人电子邮件中为附件显示的名称。

Thus you can freely choose the name parameter (extension .xls preferred), and set the mediaType parameter to "application/vnd.ms-excel", which is the defined MIME type for excel files.这样就可以自由选择name参数(扩展名.xls首选),将mediaType参数设置为“application/vnd.ms-excel”,这是excel文件定义的MIME类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM