Una form di contatti con ASP.NET Core MVC

di Moreno Gentili, in ASP.NET Core,

In molte applicazioni web è comune mettere a disposizione degli utenti un form di contatto per ricevere le loro richieste ma senza divulgare l'indirizzo e-mail del ricevente. Vediamo i passi per realizzarlo con ASP.NET Core MVC.

Installare le dipendenze

Iniziamo installando il pacchetto NuGet MailKit, che useremo per l'invio dei messaggi e-mail in sostituzione alle tradizionali classi del namespace System.Net.Mail, non essendo ancora disponibili ufficialmente per il .NET Core. Se stiamo usando Visual Studio, apriamo la Package Manager Console e digitiamo:

Install-Package MailKit

Inoltre, se intendiamo supportare la validazione dei dati lato client, assicuriamoci di avere installato jquery-validation e jquery-validation-unobtrusive. Nel caso in cui non fossero in elenco, installiamoli usando Bower che ora è il package manager consigliato per l'installazione delle dipendenze lato client.


Aggiungiamo un riferimento ai file javascript in fondo alla nostra view di layout, il cui percorso è tipicamente /Views/Shared/_Layout.cshtml.

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<!-- In questo esempio verrà usato anche Bootstrap -->
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>

Per brevità, i file sono stati referenziati qui con il loro percorso locale ma ricordiamo che è preferibile caricare le librerie javascript più comuni dai CDN. Questa tecnica è stata descritta in un precedente script (https://www.aspitalia.com/script/1246/Caricamenti-Veloci-CDN-Fallback-Locale-ASP.NET-Core.aspx).

Creare il Model

Aggiungiamo una classe Contact al nostro progetto ed inseriamo in essa le proprietà da mostrare nel form. Come nelle precedenti versioni di ASP.NET, possiamo decorare ogni proprietà con data annotation per imporre dei vincoli di validazione sui dati inseriti. Ad esempio, con l'attributo Required richiediamo l'inserimento obbligatorio del dato.

public class Contact
{
  //Obbligatorio, massimo 30 caratteri
  [Required, StringLength(30), Display(Name = "Your first and last name")]
  public string Name { get; set; }

  //Obbligatorio, dev'essere un indirizzo email valido
  [Required, EmailAddress, Display(Name = "E-mail address")]
  public string Email { get; set; }

  [Required, StringLength(100), Display(Name = "How did you hear about us?")]
  public string Source { get; set; }

  //Obbligatorio, massimo 1000 caratteri
  [Required, StringLength(1000), Display(Name = "Your message to us")]
  public string Request { get; set; }
}

Creare la View

A questo punto creiamo una view in grado di presentare il tipo di oggetto che abbiamo appena definito. All'interno della cartella /Views/Home creiamo un file Contact.cshtml con il seguente contenuto:

@model NamespaceApplicazione.Models.Contact
<h2>Contact us</h2>
<p>Fill in the form to get in touch with us.</p>
<form asp-controller="Home" asp-action="SendMail" method="post">
  <div class="form-group">
    <label asp-for="Name"></label>
    <input type="text" asp-for="Name" class="form-control" />
    <span asp-validation-for="Name" />
  </div>
  <div class="form-group">
    <label asp-for="Email"></label>
    <input type="text" asp-for="Email" class="form-control" />
    <span asp-validation-for="Email" />
  </div>
  <div class="form-group">
    <label asp-for="Source"></label>
    <select type="text" asp-for="Source" class="form-control">
      <option>advertising</option>
      <option>a search engine</option>
      <option>a friend</option>
    </select>
    <span asp-validation-for="Source" />
  </div>
  <div class="form-group">
    <label asp-for="Request"></label>
    <textarea asp-for="Request" class="form-control"></textarea>
    <span asp-validation-for="Request" />
  </div>
  <div class="form-group">
    <div asp-validation-summary="All"></div>
    <button type="submit" class="btn btn-primary btn-lg"><i class="glyphicon glyphicon-send"></i> Send</button>
  </div>
</form>
<style>
  .field-validation-error, .validation-summary-errors { color:red; }
  .input-validation-error { border-color:red; }
</style>

E' da notare come l'uso dei tag helper di ASP.NET Core MVC abbia migliorato in maniera notevole la leggibilità delle nostre view, mantenendo una sintassi prettamente dichiarativa. I tag helper impiegati sono i seguenti:

  • form, che sostituisce l'helper Html.BeginForm();
  • label, che visualizza i nomi delle proprietà del modello e sostituisce Html.LabelFor();
  • input, che sostituisce vari altri helper come Html.TextBoxFor(), Html.RadioButtonFor() e Html.CheckBoxFor(), in base al valore del suo attributo type;
  • select, che sostituisce Html.DropDownListFor() e Html.ListBoxFor();
  • textarea, che sostituisce Html.TextAreaFor();
  • span, che con il suo attributo asp-validation-for è in grado di presentare gli errori di validazione per una specifica proprietà del modello. Sostituisce Html.ValidationMessageFor();
  • div, che con il suo attributo asp-validation-summary può visualizzare tutti gli errori di validazione o solo quelli che riguardano le proprietà del modello. Sostituisce Html.ValidationSummary();

Tutti i tag helper ci permettono di indicare sia attributi propri che attributi HTML, che sono rappresentati da Visual Studio con colori diversi.

Inviare l'e-mail dal Controller

All'interno del nostro HomeController, scriviamo una prima action denominata Contact che useremo per visualizzare il modulo di contatto. Inoltre, scriviamo l'action SendMail che riceverà i dati postati dal form e li invierà via e-mail:

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

[HttpPost]
public async Task<IActionResult> SendMail(Contact contact)
{
  //Verifichiamo che non ci siano errori nei dati forniti
  if (!ModelState.IsValid)
  {
    return View(contact);
  }

  //Intestazione del messaggio
  var msg = new MimeMessage();
  msg.From.Add(new MailboxAddress(contact.Name, contact.Email));
  msg.To.Add(new MailboxAddress("Nome del ricevente", "email@example.com"));
  msg.Subject = "Contact request";
  msg.Body = new TextPart("plain")
  {
    Text = $@"{contact.Name} heard about us from {contact.Source} and asks: {contact.Request}"
  };
  
  try
  {
    //Inviamo con MailKit
    using (var client = new SmtpClient())
    {
      // A scopo di demo, accettiamo tutti i certificati SSL (se il server supporta STARTTLS)
      client.ServerCertificateValidationCallback = (s, c, h, e) => true;
      await client.ConnectAsync("smtp.example.com", port: 587, useSsl: false);

      // Qui non usiamo l'autenticazione XOAUTH2
      client.AuthenticationMechanisms.Remove("XOAUTH2");

      // Ci autentichiamo se il server SMTP lo richiede
      await client.AuthenticateAsync("nomeUtente", "password");

      await client.SendAsync(msg);
      await client.DisconnectAsync(quit: true);

      //Reindirizziamo ad una view contenente un messaggio di conferma
      return View("SendMailSuccessful");
    }
  } catch (Exception exc)
  {
      //TODO: logga l'eccezione prima di reindirizzare alla view di errore
      return View("SendMailFailed");
  }
}

Ora possiamo lanciare l'applicazione e visualizzare il risultato finale.


Nel prossimo script miglioreremo il form di contatto integrando un captcha per evitare abusi da parte di bot.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi