#c# #email #filenames #attachment #system.net.mail
#c# #Адрес электронной почты #имена файлов #вложение #system.net.mail
Вопрос:
У меня есть простое приложение на C #, которое отправляет электронные письма SMTP (используя классы System.Net.Mail). После отправки (отправки по электронной почте) объекта MailMessage я хочу выполнить итерацию по списку вложений и удалить исходные файлы, связанные с этими вложениями… но мне трудно найти полный путь к файлу, связанный с каждым вложением, без сохранения моей собственной коллекции путей к файлам вложений. Должен быть хороший способ извлечь полный путь к файлу из объекта вложения.
Я знаю, что это должно быть просто, но я трачу на это слишком много времени .. время спросить других.
Комментарии:
1. Как вы передаете файл в качестве вложения? Я не вижу конструктора вложений, который принимает имя файла напрямую. Вы передаете потоки файлов? Как вы думаете, почему объект Attachement по-прежнему будет иметь исходное имя файла?
2. @Rup Конструктор описан здесь: msdn.microsoft.com/en-us/library/ms144614.aspx . Но я не думаю, что
Attachment
объект сохраняет имя файла.3. @Joel Ах, ХОРОШО — я думал, что просто задайте имя файла MIME, а не читайте файл. В этом случае сработает мой ответ ниже: это не сохраняет имя файла в классе attachment, но вводит вложение в FileStream, чтобы вы могли прочитать имя из потока.
Ответ №1:
Если вы добавляете свои вложения через Attachment
конструктор с filePath
аргументом, эти вложения могут быть получены через ContentStream
свойство и будут иметь тип FileStream
. Вот как вы можете получить имена прикрепленных файлов:
var fileNames = message.Attachments
.Select(a => a.ContentStream)
.OfType<FileStream>()
.Select(fs => fs.Name);
Но не забудьте сначала удалить MailMessage
объект, иначе вы не сможете удалить эти вложения:
IEnumerable<string> attachments = null;
using (var message = new MailMessage())
{
...
attachments = message.Attachments
.Select(a => a.ContentStream)
.OfType<FileStream>()
.Select(fs => fs.Name);
}
foreach (var attachment in attachments )
{
File.Delete(attachment);
}
Комментарии:
1. Из-за примера кода ваш ответ был самым полезным, но у Рупа была та же идея, и он был первым, поэтому я дал ему правильный ответ … но вы получили право голоса.
Ответ №2:
Вы можете
- Прочитайте вложение.ContentStream
- Если у вас теперь есть StreamReader или аналогичный, используйте свойство BaseStream, чтобы попытаться найти внутренний FileStream
- Читать FileStream.Name
но имейте в виду, что почтовое сообщение (и, следовательно, вложения и их потоки) может быть собрано или очищено не сразу, поэтому вы не сможете сразу удалить файл. Вы могли бы сделать подкласс Attachment лучше и записать имя файла и подкласс Dispose (для выполнения после базового dispose), чтобы выполнить удаление, если вам действительно нужно сделать что-то таким образом.
Комментарии:
1. В вашей ссылке на
Attachment.ContentStream
отсутствует «x» в конце. (должен быть файл .aspx.) Я бы отредактировал его для вас, но у меня пока недостаточно репутации.
Ответ №3:
Как правило, проще всего пойти немного другим путем и прикрепить через memorystream, а не файл. Таким образом, вы избегаете всех проблем, связанных с сохранением файлов на диск и последующей их очисткой.
Комментарии:
1. Если это временный файл, который вы сгенерировали самостоятельно, вы можете установить FileOptions. Удалите OnClose и предоставьте ОС все равно его очищать.