0

I've been searching Google/SO for the past 3 days without success and hoping someone can help or point me in the right direction.

We have a method (with a bunch to overloads) that sends emails. I'm tasked with saving the email into a database.

Question

How can I extract the contents of an attachment into a byte[] in order to save it to the database?

I've read a lot of samples that saves attachments to disk, but I want to avoid saving to disk then reading that into memory (maybe that's why I haven't found anything because it's not possible, doubt it).

RoLYroLLs
  • 3,113
  • 4
  • 38
  • 57

1 Answers1

1

So I think what your asking is how to convert the stream to bytes then you will not have to save it to disk. You can use this extension method to do that.

public static class StreamExtensions
{
    public static byte[] ReadAllBytes(this Stream instream)
    {
        if (instream is MemoryStream)
            return ((MemoryStream) instream).ToArray();

        using (var memoryStream = new MemoryStream())
        {
            instream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
}

see https://stackoverflow.com/a/33611922/237109

with that method you can do this

System.Net.Mail.MailMessage m = new MailMessage();
foreach (var element in m.Attachments)
{
  byte[] bytes = element.ContentStream.ReadAllBytes()
   element.ContentType // you will want to save this as well so you can convert it to a file when you need to pull it back out of the database.
}
Micah Armantrout
  • 6,781
  • 4
  • 40
  • 66
  • interestingly it's not working. the result is always `0x`. I checked `element.ContentStream.Length` and I do get a value > 0, but `ReadAllBytes()` and other methods from that other post always return nothing. =( Side note, on a test page I made sure the upload file was working properly and it was (the email does send the attached file expected), but obviously something is happening at this stage. =( – RoLYroLLs Dec 09 '20 at 17:45
  • 1
    ok so I separated this logic to test it by itself and it works. Good start, now I just have to figure out what's happening in this method. Thanks for guide in the right direction! – RoLYroLLs Dec 10 '20 at 16:03
  • 1
    Ok so I found the problem (something I was unaware). Our `SendMail()` method accepted an `IEnumerable` for attachments. It then passed that along with other fields to build the `MailMessage` object. it was at this point where I tried to get the `Stream` of the original attachments. After further testing I realized them `Stream` could only be read once and I had lost it upon the creation of the `MailMessage` object. – RoLYroLLs Dec 10 '20 at 19:23
  • Yes the stream can only be read once but you can save the bytes and reuse that or reset the steam if you need to – Micah Armantrout Dec 10 '20 at 19:39
  • Ok. I'll have to look at how to "reset the stream" feel free to let me know how. thnaks – RoLYroLLs Dec 10 '20 at 19:42
  • I assume it's `Stream.Position = 0`? (testing now). – RoLYroLLs Dec 10 '20 at 19:48