C # Получить имя файла из вложений в почту

#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 и предоставьте ОС все равно его очищать.