2017-02-22 32 views
-2

Я провел последние 2-3 недели обучения ASP.NET Core с помощью обучающих программ Microsoft Docs, Getting Started и много поиска stackoverflow. Я могу получить, сделав простые веб-приложения из Учебников, но что-то, что выходит за рамки меня, - это создавать функции, которые работают для меня, и как обращаться к переменным из разных частей приложения.Как отправить данные формы контроллеру MVC с помощью MailKit

Моя проблема:

Использование MailKit (почтовый клиент библиотеки) с ASP.NET Core. Как некоторые могут знать, что они недавно удалили System.Net.Mail из ядра ASP.NET, поэтому я решил использовать MailKit вместо этого.

Я хотел бы получить некоторые разъяснения по некоторым вопросам, которые я отклонил под каждым соответствующим фрагментом кода.

Моя установка:

  • Wwwroot
  • Контроллеры
    • HomeController.cs
  • Модели
    • Mail.cs
  • Просмотров
    • Главная
      • Index.cshtml
    • Shared
      • _Layout.cshtml

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


Вид: Index.cshtml

<form asp-controller="Home" asp-action="SubmitInput" method="post"> 
    <input asp-for="Name" required /> 
    <input asp-for="Email" required /> 
    <input asp-for="CompanyName" required /> 
    <input asp-for="Website" required /> 
    <textarea asp-for="Message"></textarea> 
    <button type="submit">Submit</button> 
</form> 

Как отправить информацию, из Index.cshtml моей SubmitInput функции в HomeController.cs


Контроллер: HomeController.cs

namespace Project.Controllers 
{ 
    public class HomeController : Controller 
    { 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public IActionResult SubmitInput() 
     { 
      string fromEmail = Email, 
        fromName = Name, 
        toEmail = "[email protected]", 
        subject = "ASP.NET Core with MailKit" 
        content = Message 
        site =  Website, 
        company = CompanyName; 

      // MailKit 
      Models.Mail.Send(fromEmail, fromName, toEmail, subject, content); 

      return View(); 
     } 

     public IActionResult Index() 
     { 
      return View(); 
     } 

     public IActionResult Error() 
     { 
      return View(); 
     } 
    } 
} 

В HomeController.cs необходимо получить переменные из формы представления в Index.cshtml.Я просто не знаю, почему я не получаю значения из формы.


Модель: Mail.cs

namespace Project.Models 
{ 
    public class Mail 
    { 
     public static string Send(
      string fromEmail, 
      string fromName, 
      string toEmail, 
      string subject, 
      string content) 
     { 
      try 
      { 
       // Get, Set Variables 
       MimeMessage Email = new MimeMessage(); 
       Email.From.Add(new MailboxAddress(fromName, fromEmail)); 
       Email.To.Add(new MailboxAddress("", toEmail)); 
       Email.Subject = subject; 
       Email.Body = new TextPart("Plain") { Text = content }; 

       // SMTP Mail Client 
       using (var client = new SmtpClient()) 
       { 
        // Accept all SSL certificates (in case the server supports STARTTLS) 
        client.ServerCertificateValidationCallback = (s, c, h, e) => true; 

        client.Connect(
         "smtp.gmail.com", 
         587, 
         MailKit.Security.SecureSocketOptions.StartTlsWhenAvailable); 

        // Since we don't have an OAuth2 token, disable the XOAUTH2 authentication mechanism. 
        client.AuthenticationMechanisms.Remove("XOAUTH2"); 

        // Only needed if the SMTP server requires authentication 
        client.Authenticate("[email protected]", "password"); 
        client.Send(Email); 
        client.Disconnect(true); 
        return "Success"; 
       } 
      } 
      catch (Exception) 
      { 
       return "Failed"; 
      } 
     } 
    } 
} 

Я не уверен, куда поместить код MailKit в. Разрешено ли существовать в папке Model как Mail.cs?

+1

Вы спрашиваете, как получить значения из формы или как спроектировать архитектуру вашей системы? Как код MailKit * не может существовать * в папке «Модель»? –

+0

Этот вопрос не имеет ничего общего с почтой и всем, что связано с «отправкой данных формы в контроллер MVC» –

ответ

-2

HomeController.cs должен получить переменные из формы представления в Index.cshtml. Я просто не знаю, почему я не получаю значения из формы.

Я не remmember, если он по-прежнему необходимо вручную добавить анти ключ подделке в форме, как в ASP.NET MVC, но вы можете попробовать добавить asp-antiforgery="true" в форму тега, чтобы убедиться, что он посылает маркер.

Кстати, не ваше устройство SubmitInput должно получить вашу модель, чтобы получить информацию в контроллер? Как вы ожидаете передать значения? Вы должны либо использовать сильное типизированное представление, либо получить значения из словаря Request.Form.

Я не уверен, куда положить код MailKit. Допускается ли в папке «Модель» в виде Mail.cs?

Я рекомендую вам заглянуть в рельсы file strucutre для вдохновения. Обычно я делаю создание папки Helpers\Mailer для этого.

1

HomeController.cs должен получить переменные из формы представления в Index.cshtml. Я просто не знаю, почему я не получаю значения из формы.

SubmitInput способ действия не имеет параметров. Как вы ожидаете, что значения из представления будут доступны для контроллера. Если вы указали переменные Email, Message, Website и т. Д. На уровне контроллера, тогда это не так. В вашем случае вы должны попытаться получить значения от Request.Form следующим образом.

[HttpPost] 
[ValidateAntiForgeryToken] 
public IActionResult SubmitInput() 
{ 
    string fromEmail = Request.Form["Email"], 
      fromName = Request.Form["Name"], 
      toEmail = "[email protected]", 
      subject = "ASP.NET Core with MailKit", 
      content = Request.Form["Message"], 
      site =  Request.Form["Website"], 
      company = Request.Form["CompanyName"]; 

    // MailKit 
    Models.Mail.Send(fromEmail, fromName, toEmail, subject, content); 
    return View(); 
} 

Лучший способ сделать это было бы создать класс модели со всеми этими свойствами и представить значения в рамках модели объекта класса вместо Form.Request.

Я не уверен, куда положить код MailKit. Допускается ли в папке «Модель» в виде Mail.cs?

Нет никакого вреда, но это не рекомендуется. Правильный способ сделать это - это объединить функции отправки электронной почты в класс обслуживания.

public class EmailService 
{ 
    public string SendEmail(string fromEmail, 
     string fromName, 
     string toEmail, 
     string subject, 
     string content) 
    { 
     try 
     { 
      // Get, Set Variables 
      MimeMessage Email = new MimeMessage(); 
      Email.From.Add(new MailboxAddress(fromName, fromEmail)); 
      Email.To.Add(new MailboxAddress("", toEmail)); 
      Email.Subject = subject; 
      Email.Body = new TextPart("Plain") { Text = content }; 

      // SMTP Mail Client 
      using (var client = new SmtpClient()) 
      { 
       // Accept all SSL certificates (in case the server supports STARTTLS) 
       client.ServerCertificateValidationCallback = (s, c, h, e) => true; 

       client.Connect(
        "smtp.gmail.com", 
        587, MailKit.Security.SecureSocketOptions.StartTlsWhenAvailable); 

       // Since we don't have an OAuth2 token, disable the XOAUTH2 authentication mechanism. 
       client.AuthenticationMechanisms.Remove("XOAUTH2"); 

       // Only needed if the SMTP server requires authentication 
       client.Authenticate("[email protected]", "password"); 
       client.Send(Email); 
       client.Disconnect(true); 
       return "Success"; 
      } 
     } 
     catch (Exception) 
     { 
      return "Failed"; 
     } 
    } 
} 

И используйте это в своем контроллере следующим образом.

public class HomeController : Controller 
{ 
    private EmailService emailService; 
    public HomeController() 
    { 
     this.emailService = new EmailService(); 
    } 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public IActionResult SubmitInput() 
    { 
     string fromEmail = Email, 
       fromName = Name, 
       toEmail = "[email protected]", 
       subject = "ASP.NET Core with MailKit" 
       content = Message 
       site =  Website, 
       company = CompanyName; 

     var emailSentStatus = this.emailService.SendEmail(fromMail, fromName, toEmail, subject, content); 

     if(emailSentStatus == "success") 
     { 
      //Logic of email sent successfully. 
     } 
     else 
     { 
      //Logic of email not sent successfully. 
     } 
     return View(); 
    } 
} 

Это может быть дополнительно улучшено с использованием инъекции и контейнера IoC. Ради простоты я не включил это в этот ответ.