Форма с загрузкой вложений и отправкой по электронной почте

Мне нужно сделать форму с текстовым полем и полем загрузки изображений. Когда кто-то его подает, я хочу, чтобы он отправил электронную почту (с текстом из textarea) с прикреплениями (из поля ввода входного файла) мне.

Моя простая форма выглядит так:

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

    </fieldset>

}

Я нашел PHP-скрипты, которые делают что-то подобное, но как я могу сделать это в ASP.NET MVC (может быть с JavaScript)?

Ответы

Ответ 1

Вот пример использования gmail SMTP, но если у вас есть собственный SMTP-сервер, вы можете легко адаптировать код.

Как всегда, я бы начал с модели представления:

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

    public HttpPostedFileBase Attachment { get; set; }
}

тогда контроллер:

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");
    }
}

и, наконец, представление:

@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>
}

Дальнейшим усовершенствованием этого кода будет экстернализация фактической отправки почты в репозиторий, реализующий некоторый интерфейс, и использование DI, чтобы ослабить связь между логикой контроллера и логикой отправки почты.

Обратите внимание, что вы также можете настроить параметры SMTP в 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>

а затем просто:

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);
}

Ответ 2

Класс MailMessage в .NET должен иметь возможность обрабатывать это для вас:

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

Или вы ищете что-то более конкретное для вашего реального кода? (например, как прочитать файл и добавить его в приложение)?

Ответ 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);
      }
    }

Ответ 4

В дополнение к ответу Daren, вам не нужно жестко указывать ввод и метку для загрузки файла в вашем представлении. Просто нажмите здесь:)

@Html.TextBoxFor(model => model.Attachment, new { type = "file" })
@Html.LabelFor(model => model.Attachment)