Как добавить вложение к электронному письму с помощью System.Net.Mail?

У меня есть документ Excel, представленный в виде байта [], и я хочу отправить его как вложение в электронное письмо.

У меня проблемы с установкой вложения.

Я могу создать вложение, в котором есть следующие конструкторы:

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

Моя идея на данный момент состоит в том, чтобы создать MemoryStream из байта [] и передать его методу, который создает вложение.

К сожалению, я не вижу способа получить предполагаемое имя файла и тип содержимого из MemoryStream, а также не вижу, как предоставить правильный тип содержимого. Есть варианты для обычного текста, Pdf, Rtf и т. Д., Но ни один из них, который я вижу, сразу не бросается в глаза, как тот, который я должен использовать для документа Excel.

Ближайшее, что я могу найти, - это MediaTypeNames.Application .Octet, в котором говорится:

Член Octet означает, что вложение содержит общие двоичные данные.

Однако, даже если это тот, который нужно использовать, если он не может быть передан как свойство Stream, тогда мой метод отправки электронных писем сможет отправлять только byte [] как документ Excel ...

Может быть, я мог бы использовать какой-нибудь другой поток? Или мне придется создать свой собственный тип Stream, который будет содержать нужные мне детали.

Наверняка кто-то делал это раньше, и Microsoft наверняка продумала бы это до такого уровня ...

Любая помощь приветствуется.

Обновление. Не голосуйте за ответы, в которых используются конструкторы, которые принимают имя файла в виде строки. Мне действительно нужна помощь с использованием тех, которые принимают Stream ... Я хочу избежать необходимости записывать файл на диск, отправлять его по электронной почте, а затем немедленно удалять его. Поскольку есть метод, который позволяет мне это сделать, я хотел бы использовать его, если это вообще возможно.

Обновление решения

Конраду удалось найти то, что я искал! Большое спасибо, чувак!

Я просто задокументирую предлагаемое решение на случай, если что-то случится с контентом по предоставленной ссылке.

Благодарим за это решение www.systemnetmail.com

static void AttachmentFromStream()
{

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

//set the addresses
mail.From = new MailAddress("[email protected]");
mail.To.Add("[email protected]");

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

В моем случае это просто означает, что мне придется изменить свой метод, чтобы имя файла и формат файла принимались как строки. Я попробую использовать Octet ... но в противном случае я просто передам официальный тип MIME.

Учитывая все обстоятельства, это довольно очевидное решение ... но я ценю помощь в его решении ... и хорошо, что это решение будет задокументировано для будущих программистов, у которых возникнет такая же проблема.

Еще раз спасибо всем за помощь!


person mezoid    schedule 09.02.2009    source источник


Ответы (5)


У конструктора вложений действительно есть конструктор, который делает то, что вам нужно. Я предполагаю, что вы используете класс System.Net.MailMessage из .NET Framework 2. Если да, то прочтите эту ссылку, чтобы получить образец кода того, что вам нужно

person Rad    schedule 09.02.2009
comment
Спасибо! Это именно то, что я искал. Как вам это удалось? Я полагаю, мы оба используем один и тот же Google для поиска? - person mezoid; 09.02.2009
comment
Ха-ха! Что ж, скажем так, работая m, я трачу много времени на поиски ответов на проблемы! - person Rad; 10.02.2009
comment
Спасибо Рад, очень удобная ссылка, что - person JsonStatham; 15.09.2014
comment
Не упоминается в этой ссылке, но убедитесь, что вы Удалите свои вложения (которые удаляют базовые потоки) или вызовите mail.Dispose(), который сделает это за вас. - person Dunc; 06.10.2016
comment
Ссылка мертва. Да здравствует репост! stackoverflow.com/a/45286897/1037948 - person drzaus; 24.07.2017

Поскольку ссылка из принятый ответ пропал, вот он из Wayback Machine

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

Полный:

static void AttachmentFromStream()
{

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

    //set the addresses
    mail.From = new MailAddress("[email protected]");
    mail.To.Add("[email protected]");

    //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;
}
person drzaus    schedule 24.07.2017

Получил этот ответ от Microsoft docs:

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(
        "[email protected]",
        "[email protected]",
        "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();
}
person Michel El Hajj    schedule 03.12.2020

Параметр name в конструкторе Attachment - это имя, которое будет отображаться для вложения в электронном письме получателя.

Таким образом, вы можете свободно выбрать параметр имени (предпочтительно расширение .xls) и установить для параметра mediaType значение «application / vnd.ms-excel», которое является определенным MIME-тип для файлов Excel.

person devio    schedule 09.02.2009

--------------- Думаю, я ошибаюсь, это если у вас есть файл, который вы хотите прикрепить ---------------

похоже, здесь есть пример отправки почты с вложением:

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

Надеюсь, это то, что вы ищете.

person John Boker    schedule 09.02.2009
comment
к сожалению, не потому, что метод, использованный в этом примере, заключается в передаче строки с именем файла ... что означает, что файл должен быть записан на диск перед его отправкой. Я хочу сделать все это в памяти, так как у меня нет причин записывать файл на диск, отправлять его, а затем удалять файл .. - person mezoid; 09.02.2009
comment
извините, что проголосовал против вашего ответа, Джон, но кто-то проголосовал за него, и это неправильный ответ. Пожалуйста, никто другой не голосует за этот ответ ... Мне нужно создать вложение, используя конструкторы, которые принимают Stream, а не строку. - person mezoid; 09.02.2009