How do I add an attachment to an email using Syste

2020-02-04 08:16发布

问题:

I have an excel document represented as a byte[] and I'm wanting to send it as an attachment in an email.

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.

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. 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.

The closest I can find is MediaTypeNames.Application.Octet which states:

The Octet member designates that the attachment contains generic binary data.

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...

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.

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. 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

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.

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!

回答1:

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



回答2:

Since the link from the accepted answer is gone, here it is from the Wayback Machine

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;
}


回答3:

The name parameter in the Attachment constructor is the name that will be displayed for the attachment in the recipient's email.

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.



回答4:

--------------- 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

I hope this is what you're looking for.