Tuesday, October 19, 2010

Email attachments - using memory stream

In my previous post I mentioned about a task where I had to send HTML mails. In each of the emails, I also had to attach a file. The files were dynamically created and I wanted to avoid having to physically create the files on the servers, attach the files to the mail and then having to delete it.

I found that it is possible to attach files as memory streams using
Message.Attachments.Add(memoryStream, ...

But as I wrote the code to do this, I found that the size of the file been attached was always 0 kb. So back to the trouble shooting ..

I was creating the file in a different assembly and the file was been received as a memory stream. So the code looked something like this

Class A
- Get details to create the file from database
- Call a method in Class B to create the file and store the returned memory stream in local variale
- Call a method in class C to send mails and pass the local memory stream to this method

Class B
- create a new file and return the file as memory stream object

Class C
- Create a mailmessage.
- Attach the file received as memorystream parameter to the mail message
- send the mail.

Everything seemed right. I even debugged the code to ensure that the memorystream object been created in class B was not empty. I debugged to see if the memory stream received by the method in class C had all the proper content and was not empty. Again everything looked fine. So where was the problem. Various people on the internet seemed to suggest flusing the memomorystream, moving the position to 0, etc but nothing worked

I finally realized that when files are attached as a memory stream to emails, the stream needs to be open. So first I tried by not closing the stream in Class B. But that did not work. So in class C before attaching the file to the mail message, I created a new stream using the same stream I got as a parameter, like this

MemoryStream memoryStream = new MemoryStream(pMyStream.ToArray());
MyMailMessage.Attachments.Add(new Attachment(memoryStream, "Name.pdf", MediaTypeNames.Application.Pdf));


and that worked !!

6 comments:

  1. thanks !! that worked for me too

    ReplyDelete
  2. Hi
    Thanks for the post, this gave me some relief after five hours of frustration.

    But I still don't get why its working? I created a basic memorystream, added it as email attachment while keeping memory stream open, but still didnt work.

    Creating the second memory stream works like you say. Confusing :S

    Regards
    David

    ReplyDelete
  3. Thanks for this! Creating the 2nd stream worked for me too.

    ReplyDelete
  4. I had the same issue using StreamWriter and MemoryStream. I found that you have to flush the StreamWriter first, then set the MemoryStream position to 0.

    streamWriter.Flush();
    memoryStream.Position = 0;

    And it worked.

    ReplyDelete