9

I am trying to get an uploaded file to be sent as an attachment in my ashx file. Here is the code I am using:

HttpPostedFile fileupload = context.Request.Files[0];

//filename w/o the path
string file = Path.GetFileName(fileupload.FileName);

MailMessage message = new MailMessage();

//*****useless stuff********
message.To.Add("abc@xxx.com");
message.Subject = "test";
message.From = new MailAddress("test@aaa.com");
message.IsBodyHtml = true;
message.Body = "testing";
 //*****useless stuff********

//Fault line
message.Attachments.Add(new Attachment(file, MediaTypeNames.Application.Octet))

//Send mail 
SmtpClient smtp = new System.Net.Mail.SmtpClient("xxxx", 25);
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("xxx", "xxxx");
smtp.Send(message);

I am able to send the email without the attachment. Do I need to save the file first and then add to attachment?

Michael
  • 8,362
  • 6
  • 61
  • 88
nikhil
  • 211
  • 1
  • 2
  • 11
  • You need to save the file first; see a similar question involving attaching an image to a mail message here: http://stackoverflow.com/questions/6105904/how-to-send-image-as-attachement-without-saving-it-in-file-system – dash Dec 13 '11 at 22:54
  • Yea got the thing. I couldn't use Server.MapPath(). the solution is HttpContext.Current.Server.MapPath(). – nikhil Dec 13 '11 at 23:20

4 Answers4

19

You do NOT need to, nor should you, save attachments to the server unnecessarily. ASP Snippets has an article on how to do it in ASP.NET WebForms.

Doing it in C# MVC is even nicer:

public IEnumerable<HttpPostedFileBase> UploadedFiles { get; set; }

var mailMessage = new MailMessage();
// ... To, Subject, Body, etc

foreach (var file in UploadedFiles)
{
    if (file != null && file.ContentLength > 0)
    {
        try
        {
            string fileName = Path.GetFileName(file.FileName);
            var attachment = new Attachment(file.InputStream, fileName);
            mailMessage.Attachments.Add(attachment);
        }
        catch(Exception) { }
    }
}
Michael
  • 8,362
  • 6
  • 61
  • 88
Serj Sagan
  • 28,927
  • 17
  • 154
  • 183
5

Following in the footsteps of Serj Sagan, here's a handler using webforms, but with <input type="file" name="upload_your_file" /> instead of the <asp:FileUpload> control:

HttpPostedFile file = Request.Files["upload_your_file"];
if (file != null && file.ContentLength > 0)
{
    string fileName = Path.GetFileName(file.FileName);
    var attachment = new Attachment(file.InputStream, fileName);
    mailMessage.Attachments.Add(attachment);
}

This is useful if you don't need (or can't add) a runat="server" on your form tag.

Community
  • 1
  • 1
Michael
  • 8,362
  • 6
  • 61
  • 88
2

You can do like this:

private  void btnSend_Click(object sender,EventArgs e)
{
    MailMessage myMail = new MailMessage();
    myMail.To = this.txtTo.Text;
    myMail.From = "<" + this.txtFromEmail.Text + ">" + this.txtFromName.Text;
    myMail.Subject = this.txtSubject.Text;

    myMail.BodyFormat = MailFormat.Html;
    myMail.Body = this.txtDescription.Text.Replace("\n","<br>");

    //*** Files 1 ***//
    if(this.fiUpload1.HasFile)
    {
        this.fiUpload1.SaveAs(Server.MapPath("MyAttach/"+fiUpload1.FileName));
        myMail.Attachments.Add(new MailAttachment(Server.MapPath("MyAttach/"+fiUpload1.FileName)));
    }

    //*** Files 2 ***//
    if(this.fiUpload2.HasFile)
    {
        this.fiUpload2.SaveAs(Server.MapPath("MyAttach/"+fiUpload2.FileName));
        myMail.Attachments.Add(new MailAttachment(Server.MapPath("MyAttach/"+fiUpload2.FileName)));
    }


    SmtpMail.Send(myMail);
    myMail = null;
    this.pnlForm.Visible = false;
    this.lblText.Text = "Mail Sending.";
}
Himanshu
  • 31,810
  • 31
  • 111
  • 133
Glory Raj
  • 17,397
  • 27
  • 100
  • 203
0

FileName is the name of the file on the client, not on the server. You will need to use SaveAs or the InputStream to get any content into the attachment.

Here is a link to the MSDN documentation.

competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • 6
    You do NOT need to save it to disk first... that is bad practice. – Serj Sagan Nov 12 '13 at 17:02
  • @SerjSagan: I'm sorry, but you are incorrect. It is a best practice in any type of corporate environment or any environment that cares at all about security. Saving to disk first allows anti-virus checkers to scan the file prior to moving to any location beyond the web server, thus preventing the spread of potential malware into the internal network. – competent_tech Nov 12 '13 at 19:18
  • 6
    Any environment that cares about security will have antivirus on the end-user's machine. By saving a file to the server you are 1) needlessly wasting server resources and 2) potentially introducing a virus to the server that an antivirus may not be aware of. It is much easier to clean a workstation rather than a server. – Serj Sagan Nov 12 '13 at 20:43
  • 1
    Seriously? So when you host a web site, you can guarantee that every user that is uploading files to your web site has antivirus installed? And, even if it is the corporate policy for end users, it is standard policy to double-check the incoming file in case the user's system has been compromised. – competent_tech Nov 12 '13 at 21:03
  • 6
    Not the users uploading but the users that are going to be receiving the uploaded files. The internal corporate users will be the ones that will be receiving these files and they will be on a system that is using an enterprise level antivirus with all of the latest definitions. And again, it is much easier to clean a compromised workstation than a compromised web server. Uploading a potentially infected file to your server could be a very dangerous thing to do, potentially exposing all of your sensitive data to the attacker. One should never put a server at risk... – Serj Sagan Nov 12 '13 at 22:29