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
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare i primary constructor di C# per inizializzare le proprietà
Migliorare i tempi di risposta di GPT tramite lo streaming endpoint in ASP.NET Core
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Ottimizzare il mapping di liste di tipi semplici con Entity Framework Core
Creare una libreria CSS universale: Immagini
Sostituire la GitHub Action di login su private registry
Utilizzare il trigger SQL con le Azure Function
Evitare il flickering dei componenti nel prerender di Blazor 8
Generare un hash con SHA-3 in .NET
Migliorare la scalabilità delle Azure Function con il Flex Consumption
Utilizzare Model as a Service su Microsoft Azure
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online