2

I am currently providing a form in MVC3 for a user to fill in some fields and attach a file. On submission, I send the information posted (with the attachment) twice... one to the poster as a receipt, and the second to another target email.

The issue that I am having is the first email gets sent successfully with the right attachemnt. The second email gets sent out with an attached file that is 0 in size. It seems that after I make an attachment object from a file upload, I cannot reuse it again. Using the debugger I can see that the file upload object is still in memory, buts its ContentLength becomes 0.

So in the following example, if I simplify my code as follows:

public static void SendDummyEmail1()
{
    using (var mailMessage = new MailMessage("from@email.com", "to@email.com"))
    {
        mailMessage.Subject = "Email Subject"
        mailMessage.Body = Razor.Parse(template, (dynamic)dynamicTokens);
        mailMessage.IsBodyHtml = true;

        if (_fileUpload != null && _fileUpload.ContentLength > 0)
        {
            var attachment = new Attachment(_fileUpload.InputStream, _fileUpload.FileName, MediaTypeNames.Application.Octet);
            attachment.ContentDisposition.FileName = Path.GetFileName(_fileUpload.FileName);
            mailMessage.Attachments.Add(attachment);
        }

        SendMail(mailMessage);
    }
}

public static void SendMail(MailMessage message)
{
    var client = new SmtpClient
    {
        Host = ConfigurationManager.AppSettings[SmtpHostname],
        Port = Convert.ToInt32(ConfigurationManager.AppSettings[SmtpPortNumber]),
        UseDefaultCredentials = true,
        Credentials = CredentialCache.DefaultNetworkCredentials,
        DeliveryMethod = SmtpDeliveryMethod.Network,
        EnableSsl = true,  
    };

    // Work around remote certificate validation
    // Ref: http://stackoverflow.com/questions/777607/the-remote-certificate-is-invalid-according-to-the-validation-procedure-using
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

    client.Send(message);
}

If I was to call the above method twice in a row, the first email will go through successfully. The second email will go through but with no attachment because the ContentLength goes to 0.

SendDummyEmail1();
SendDummyEmail1();
Hady
  • 2,597
  • 2
  • 29
  • 34
  • you already posted the file to the server for first time. so next time there is no files in request. – Ravi Gadag Feb 28 '13 at 10:55
  • follow this link http://stackoverflow.com/questions/12356817/can-not-attach-multiple-files-in-the-attachment-of-email-in-c-sharp/27705328#27705328 – Rajib Chy Dec 30 '14 at 12:22

3 Answers3

3

I suppose _fileUpload.InputStream.CanSeek in your case equals to false, which means you cannot wind it up again (Position = 0) and read from it. Try to copy uploaded file stream into memory stream first and then use it instead of initial stream, like this:

MemoryStream ms = new MemoryStream();
_fileUpload.InputStream.CopyTo(ms);
byte[] data = ms.ToArray();
SendDummyEmail1(data);
SendDummyEmail1(data);

public static void SendDummyEmail1(byte[] fileContent)
{
 ...
 var attachment = new Attachment(new MemoryStream(fileContent), ...
}
Dima
  • 6,721
  • 4
  • 24
  • 43
3

Use a memory stream as your instance variable rather than _fileUpload. Then clone that to a new steam for each email (so don't have multiple consumers). Remember to reset the streams after writing to them so that the attachment read starts from the beginning

kiwidev
  • 321
  • 1
  • 7
0

Store uploaded file on server and use file path in Attachment.

var attachment = new Attachment(filePath, MediaTypeNames.Application.Octet);

Delete uploaded file if require after sending email.

Morbia
  • 4,144
  • 3
  • 21
  • 13
  • That doesn't explain the above behaviour. It is also too much of a hassle saving the file on the server with a unique name, and cleaning up after sending. – Hady Feb 28 '13 at 10:22