C# Get filename from mail attachements
Asked Answered
J

3

8

I have a simple C# app that send SMTP emails (using System.Net.Mail classes). After sending (emailing) a MailMessage object I want to iterate through the list of the attachments and delete the original files associated with those attachments... but I am having a hard time finding the full file path associated with each attachment - without keeping my own collection of attachment filepaths. There has got to be a good way to extract the full file path from the attachment object.

I know this has got to be simple, but I am spending way to much time on this..time to ask others.

Jaf answered 6/5, 2011 at 14:11 Comment(3)
How are you passing the file in as an attachment? I can't see an Attachment constructor that accepts a filename directly. Are you passing in FileStreams? Why do you think the Attachement object will still have the source filename?Kleiman
@Kleiman The Constructor is described here: msdn.microsoft.com/en-us/library/ms144614.aspx. But I don't think the Attachment object retains the filename.Mellissamellitz
@Joel Ah, OK - I thought that just set the MIME filename not read the file. In that case my answer below will work: that doesn't save the filename in the attachment class but inits the attachment with a FileStream so you can read the name from the stream.Kleiman
K
3

You can

but bear in mind that the mail message (and hence attachments and their streams) may not get collected or cleaned up immediately, so you may not be able to delete the file straight away. You might do better subclassing Attachment and both record the filename and subclass Dispose (to execute after the base dispose) to do the delete if you really do need to do things this way.

Kleiman answered 6/5, 2011 at 14:37 Comment(1)
Your link to Attachment.ContentStream is missing an "x" at the end. (should be .aspx file.) I'd edit it for you, but don't have enough rep yet.Mellissamellitz
A
8

If you adding your attachments through the Attachment constructor with filePath argument, these attachments can be retrieved through ContentStream property and will be of type FileStream. Here is how you can get file names of the files attached:

var fileNames = message.Attachments
    .Select(a => a.ContentStream)
    .OfType<FileStream>()
    .Select(fs => fs.Name);

But don't forget to dispose MailMessage object first, otherwise you won't be able to delete these attachments:

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);
}
Adalbertoadalheid answered 6/5, 2011 at 14:39 Comment(1)
Because of the code example your response was the most helpful, but Rup had the same idea, and he was first, so I gave him the correct response...but you got a vote.Jaf
K
3

You can

but bear in mind that the mail message (and hence attachments and their streams) may not get collected or cleaned up immediately, so you may not be able to delete the file straight away. You might do better subclassing Attachment and both record the filename and subclass Dispose (to execute after the base dispose) to do the delete if you really do need to do things this way.

Kleiman answered 6/5, 2011 at 14:37 Comment(1)
Your link to Attachment.ContentStream is missing an "x" at the end. (should be .aspx file.) I'd edit it for you, but don't have enough rep yet.Mellissamellitz
I
1

It's generally easiest to take a slightly different tack and attach via a memorystream rather than a file. That way you avoid all the issues around saving the files to disk and cleaning them up afterwards.

Short article here on that.

Iceman answered 6/5, 2011 at 14:21 Comment(1)
If it's a temp file you've generated yourself then you can set FileOptions.DeleteOnClose and leave the OS to clean it up anyway.Kleiman

© 2022 - 2024 — McMap. All rights reserved.