views:

1521

answers:

2

I've got a project where I'm using a PDF generator to send a file to a user. We'd like to give the user the option to attach this file to an email instead, and we're having trouble using the Stream object and Attachment logic together.

We start with ABCpdf, which has two save methods: it can save to a Stream, or if you give it a string, it'll try to save to a file on the disk there. We've done both no problem.

Stream stream = new MemoryStream();
myPdf.Save(stream);

Everything is mostly cool at this point - stream has several kilobytes of data, and if you .Save() to a file, you get an actual file with the same number of bytes.

So we attach to an email at this point (after initializing the mail object, setting To: and From:, etc.):

mail.Attachments.Add(new Attachment(stream, "myPdf.pdf"));
mail.Send();

...which gets us as far as receiving an email with 0 bytes, but the proper filename.

All the examples I'm finding online use a StreamReader or a StreamWriter or a Flush() or something. It always seems like it's more complicated than simply passing a Stream, but maybe only one or two lines more complicated. None of those examples start with a Stream - they're always trying to turn an array into a Stream to show you how easy that is, or grab a file from disk (which we can't do, which is why we're excited to use a Stream).

Anyway, if anyone can explain what I'm doing wrong or what I ought to be doing, I'd really appreciate it. Thanks.

A: 

Have you tried saving the file and then attaching the file, rather than attempting to attach a stream?

added

The normal process here would be

  1. Use the stream to create a file on disk

  2. Attach the file to an email

  3. Delete the file when done with it.

David Stratton
Saving to disk wouldn't be an option. Are you thinking of "saving" somewhere else? Converting Stream to byte[] or something and reading that back out?
dnord
OK. If saving to a disk is not an option, then I apologize, my post will be completely unhelpful. I've never tried attaching a stream to an email. I'll check back to see what others post because I think that would be better than creating a temp file like I usually do and then having to delete it.
David Stratton
+6  A: 

A guess... Back dat stream up to the beginning before sending nit

// Set the position to the beginning of the stream.
stream.Seek(0, SeekOrigin.Begin);
mail.Attachments.Add(new Attachment(stream, "myPdf.pdf"));
mail.Send();
Will
I was meaning to try that - I'll give it a shot. Thanks.
dnord
That should be the issue. Unless you or your PDF api is using buffered streams. Don't assume; check the type of the stream at the last moment.
Will
I'd recommend using "stream.Position = 0;" as a simpler way of rewinding the stream. They're equivalent, but `Position` is more readable IMO :)
Jon Skeet
That worked. Thanks again.
dnord
Worked for me as well! I was pulling my hair out over this.
Saif Khan
I just had to do this again, and just forgot to do it again, and then I remembered to do this again, and again it works. Thanks!
dnord