Form with attachments upload and email sending

21,050

Solution 1

Here's an example using gmail's SMTP but if you have your own SMTP server you could easily adapt the code.

As always I would start with a view model:

public class QuestionViewModel
{
    [Required]
    public string Question { get; set; }

    public HttpPostedFileBase Attachment { get; set; }
}

then a controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new QuestionViewModel());
    }

    [HttpPost]
    public ActionResult Index(QuestionViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        using (var client = new SmtpClient("smtp.gmail.com", 587))
        {
            client.EnableSsl = true;
            client.Credentials = new NetworkCredential("[email protected]", "secret");
            var mail = new MailMessage();
            mail.From = new MailAddress("[email protected]");
            mail.To.Add("[email protected]");
            mail.Subject = "Test mail";
            mail.Body = model.Question;
            if (model.Attachment != null && model.Attachment.ContentLength > 0)
            {
                var attachment = new Attachment(model.Attachment.InputStream, model.Attachment.FileName);
                mail.Attachments.Add(attachment);
            }
            client.Send(mail);
        }
        return Content("email sent", "text/plain");
    }
}

and finally a view:

@model QuestionViewModel

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)
    <fieldset>        
        <div>
            @Html.LabelFor(x => x.Question)
            @Html.TextAreaFor(x => x.Question)
        </div>
        <div>
            <label for="attachment">Attachment</label>
            <input type="file" name="attachment" id="attachment"/> 
        </div>
        <input type="submit" value="Send" />
    </fieldset>
}

A further improvement to this code would be to externalize the actual sending of the mail into a repository implementing some interface and using DI in order to weaken the coupling between the controller logic and the mail sending logic.

Note that you can also configure your SMTP settings in web.config:

<system.net>
    <mailSettings>
      <smtp from="[email protected]" deliveryMethod="Network">
        <network 
          enableSsl="true" 
          host="smtp.gmail.com" 
          port="587" 
          userName="[email protected]" 
          password="secret" 
        />
      </smtp>
    </mailSettings>
</system.net>

and then simply:

using (var client = new SmtpClient())
{
    var mail = new MailMessage();
    mail.To.Add("[email protected]");
    mail.Subject = "Test mail";
    mail.Body = model.Question;
    if (model.Attachment != null && model.Attachment.ContentLength > 0)
    {
        var attachment = new Attachment(model.Attachment.InputStream, model.Attachment.FileName);
        mail.Attachments.Add(attachment);
    }
    client.Send(mail);
}

Solution 2

MailMessage class in .NET should be able to handle that for you:

http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.attachments.aspx

Or are you looking for something more specific to your actual code? (e.g. how to read the file and add it to the attachment)?

Solution 3

  if (model.Attachment != null && model.Attachment.ContentLength > 0)
    {
    foreach (HttpPostedFileBase item in fileUploader)
      {

        var attachment = new Attachment(model.Attachment.InputStream,   model.Attachment.FileName);
        mail.Attachments.Add(attachment);
      }
    }
Share:
21,050

Related videos on Youtube

Marta
Author by

Marta

Updated on February 17, 2020

Comments

  • Marta
    Marta about 4 years

    I need to make form with a textarea and an image upload field. When somebody submit it I want it to send email (with text from textarea) with attachements (from input file upload field) to me.

    My simple form looks like that:

    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
        <fieldset>        
                @Html.TextArea("Question");      
                <input type="file"/> 
                <input type="submit" value="Send" />
    
        </fieldset>
    
    }
    

    I found PHP scripts that are doing something like that, but how could I do it in ASP.NET MVC (could be with JavaScript)?

  • Marta
    Marta almost 13 years
    Yes I am looking for something more specific - how to read file from form and add it as attachment to email and then send this email.
  • Kevin Nelson
    Kevin Nelson almost 13 years
    Sorry, too slow, but glad someone got you the answer :)
  • AaronLS
    AaronLS over 12 years
    toaddress? I didn't know toads wore dresses!
  • AdrianoRR
    AdrianoRR over 12 years
    What if you tried to use a $.ajax to pass your HttpPostedFileBase file? I'm trying to do it throught a simple $.ajax call, but i got a null file on my controller. Is it the content type i'm missing?
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @AdrianoRR, it is very difficult to upload files using AJAX. There are some components out there that do it like valums.com/ajax-upload In order to upload a file you need to use multipart/form-data enctype.
  • AdrianoRR
    AdrianoRR over 12 years
    Well i didn't know about this difficulty. And yes, i'm already using multipart/form-data which is fine if i use a normal submit action, but not if i handle the .submit event with jquery. I'll check this component you mentioned. Thanks.
  • AdrianoRR
    AdrianoRR over 12 years
    Oh i forgot! If i use Ajax.BeginForm() - the bad MS ajax script - i can get a HttpPostedFileBase file on my controller. Don't know how it recognizes it, but it does.
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @AdrianoRR, are you sure that you are performing a real AJAX request? Maybe you forgot to include the jquery.unobtrusive-ajax.js script to your page in which case the Ajax.BeginForm helper behaves as a normal form?
  • AdrianoRR
    AdrianoRR over 12 years
    Oh i see! Yes, i've removed jquery.unobtrusive-ajax.js. That explains why it worked back then. Well, i still have to do this through an ajax call, since my upload occurs in a jquery.dialog(). Thanks for your help Darin!
  • BerggreenDK
    BerggreenDK over 11 years
    Cool sample Darin. Helped me forward a LOT!
  • Mark
    Mark over 9 years
    Thank you for this answer, i have been trying to do this all afternoon, this worked first try!