Esercizio: Connettere un'applicazione ASP.NET al database SQL di Azure
Il database è stato creato. È ora il momento di configurare e distribuire un'applicazione Web che i consulenti didattici possono usare per discutere corsi e piani di studio con gli studenti. L'app usa la libreria System.Data.SqlClient
per recuperare e visualizzare i dettagli dei corsi e i moduli che gli studenti devono superare per completare un corso.
Per risparmiare tempo, viene usata un'applicazione Web preesistente e viene illustrato come aggiungere il codice che connette l'app al database. Il diagramma seguente illustra i componenti principali dell'app:
Per configurare l'applicazione Web, eseguire le operazioni seguenti:
- Creare una classe contenente il nome del corso, il titolo del modulo e la sequenza per ogni modulo del database.
- Creare una classe controller di accesso ai dati che recuperi le informazioni dal database.
- Modificare il codice dietro la pagina di indice nell'app Web, per creare un oggetto controller di accesso ai dati e recuperare i dati.
- Modificare la pagina di indice per visualizzare i dati.
Distribuire ed eseguire l'app Web preesistente
Modificare la directory di lavoro nella
education
cartella .cd ~/education
Eseguire i comandi seguenti per compilare e distribuire l'app Web iniziale.
WEBAPPNAME=educationapp-$RANDOM az webapp up \ --resource-group <rgn>[Sandbox resource group]</rgn> \ --location centralus \ --sku F1 \ --name $WEBAPPNAME
Una volta distribuita l'applicazione Web, l'output visualizza un elemento App_url con l'URL del sito Web. Aprire questo sito in una nuova scheda.
Si vuole che l'app Web visualizzi l'elenco dei corsi e dei moduli che compongono ogni corso. Attualmente l'app non recupera né visualizza questi dati. È quindi necessario aggiornare il codice per ottenere i dati dal database e visualizzarli.
Aggiungere codice all'app Web per recuperare i dati
A questo punto è possibile aggiungere all'applicazione il codice necessario per recuperare i dati dei corsi dal database.
In Cloud Shell passare alla cartella
education/Models
.cd ~/education/Models
Questa cartella contiene due file,
CoursesAndModules.cs
eDataAccessController.cs
.Usare l'editor di codice per aprire il file
CoursesAndModules.cs
.code CoursesAndModules.cs
Questo file contiene una classe vuota denominata
CoursesAndModules
.namespace CoursesWebApp.Models { public class CoursesAndModules { // TODO: Define the CourseName, ModuleTitle, and Sequence read-only properties // TODO: Create a constructor that initializes the fields behind the properties } }
Sostituire il commento
// TODO: Define the CourseName, ModuleTitle, and Sequence read-only properties
con il codice seguente.public string CourseName { get; } public string ModuleTitle { get; } public int Sequence { get; }
Questo codice definisce un set di campi di sola lettura che contiene i dati per ogni riga visualizzata dall'app Web.
Sostituire il commento
// TODO: Create a constructor that initializes the fields behind the properties
con il costruttore seguente.public CoursesAndModules(string courseName, string moduleTitle, int sequence) { this.CourseName = courseName; this.ModuleTitle = moduleTitle; this.Sequence = sequence; }
Questo costruttore popola i campi con i dati da visualizzare. Il file completo dovrebbe contenere il codice seguente.
namespace CoursesWebApp.Models { public class CoursesAndModules { public string CourseName { get; } public string ModuleTitle { get; } public int Sequence { get; } public CoursesAndModules(string courseName, string moduleTitle, int sequence) { this.CourseName = courseName; this.ModuleTitle = moduleTitle; this.Sequence = sequence; } } }
Salvare il file premendo CTRL+S e chiudere l'editor di codice premendo CTRL+Q.
Usare l'editor di codice per aprire il file
DataAccessController.cs
.code DataAccessController.cs
Questo file contiene una classe denominata
DataAccessController
. La classe contiene la logica di accesso ai dati per la connessione al database e il recupero dei dati dei corsi e dei moduli. Con questi dati viene popolato un elenco di oggettiCoursesAndModules
.using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; namespace CoursesWebApp.Models { public class DataAccessController { // TODO: Add your connection string in the following statements private string connectionString = "<Azure SQL Database Connection String>"; // Retrieve all details of courses and their modules public IEnumerable<CoursesAndModules> GetAllCoursesAndModules() { List<CoursesAndModules> courseList = new List<CoursesAndModules>(); // TODO: Connect to the database //using () { // TODO: Specify the Transact-SQL query to run // TODO: Execute the query // TODO: Read the data a row at a time // TODO: Close the database connection } return courseList; } } }
Lasciare aperto l'editor di codice e passare al portale di Azure.
Nel menu del portale di Azure selezionare Database SQL e quindi selezionare il database. Viene visualizzato il database SQL per coursedatabaseNNN.
Nel riquadro del menu a sinistra, in Impostazioni selezionare Stringhe di connessione. Copiare la stringa di connessione ADO.NET negli Appunti.
Tornare all'editor di codice. Sostituire il valore della variabile connectionString con il valore contenuto negli Appunti. Nella stringa di connessione individuare il testo
User ID
con il valoreazuresql
. Sostituire il testo{your_password}
con la password per questo account.private string connectionString = "Server=tcp:courseservernnn.database.windows.net,1433;Initial Catalog=coursedatabasennn;Persist Security Info=False;User ID=azuresql;Password=<password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
Dopo il commento
//TODO: Connect to the database
, sostituire l'istruzioneusing
impostata come commento con il codice seguente.using (SqlConnection con = new SqlConnection(connectionString))
Questo codice crea un nuovo oggetto
SqlConnection
che usa la stringa di connessione per connettersi al database.Sostituire il commento
// TODO: Specify the Transact-SQL query to run
con le istruzioni seguenti.SqlCommand cmd = new SqlCommand( @"SELECT c.CourseName, m.ModuleTitle, s.ModuleSequence FROM dbo.Courses c JOIN dbo.StudyPlans s ON c.CourseID = s.CourseID JOIN dbo.Modules m ON m.ModuleCode = s.ModuleCode ORDER BY c.CourseName, s.ModuleSequence", con); cmd.CommandType = CommandType.Text;
L'oggetto
SqlCommand
contiene un'istruzione Transact-SQL (T-SQL) che recupera i dati per tutti i corsi e i moduli. Li unisce usando le informazioni nelladbo.StudyPlan
tabella.Sostituire il commento
// TODO: Execute the query
con il codice seguente.con.Open(); SqlDataReader rdr = cmd.ExecuteReader();
Queste istruzioni aprono la connessione al database ed eseguono l'istruzione T-SQL. È possibile usare l'oggetto
SqlDataReader
per recuperare i risultati una riga alla volta.Sostituire il commento
// TODO: Read the data a row at a time
con il seguente blocco di codice.while (rdr.Read()) { string courseName = rdr["CourseName"].ToString(); string moduleTitle = rdr["ModuleTitle"].ToString(); int moduleSequence = Convert.ToInt32(rdr["ModuleSequence"]); CoursesAndModules course = new CoursesAndModules(courseName, moduleTitle, moduleSequence); courseList.Add(course); }
Il blocco esegue l'iterazione nelle righe restituite nell'oggetto
SqlDataReader
. Il codice estrae i dati dei campi in ogni riga e li usa per popolare un nuovo oggettoCoursesAndModules
. Questo oggetto viene quindi aggiunto a un elenco.Sostituire il commento
// TODO: Close the database connection
con l'istruzione seguente.con.Close();
Questa istruzione chiude la connessione al database e rilascia le risorse usate.
La classe completata deve contenere il codice seguente, che include la stringa di connessione per il database.
using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; namespace CoursesWebApp.Models { public class DataAccessController { // Add your connection string in the following statements private string connectionString = "Server=tcp:courseserver101.database.windows.net,1433;Initial Catalog=coursedatabase101;Persist Security Info=False;User ID=azuresql;Password=<password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; // Retrieve all details of courses and their modules public IEnumerable<CoursesAndModules> GetAllCoursesAndModules() { List<CoursesAndModules> courseList = new List<CoursesAndModules>(); // Connect to the database using (SqlConnection con = new SqlConnection(connectionString)) { // Specify the Transact-SQL query to run SqlCommand cmd = new SqlCommand( @"SELECT c.CourseName, m.ModuleTitle, s.ModuleSequence FROM dbo.Courses c JOIN dbo.StudyPlans s ON c.CourseID = s.CourseID JOIN dbo.Modules m ON m.ModuleCode = s.ModuleCode ORDER BY c.CourseName, s.ModuleSequence", con); cmd.CommandType = CommandType.Text; // Execute the query con.Open(); SqlDataReader rdr = cmd.ExecuteReader(); // Read the data a row at a time while (rdr.Read()) { string courseName = rdr["CourseName"].ToString(); string moduleTitle = rdr["ModuleTitle"].ToString(); int moduleSequence = Convert.ToInt32(rdr["ModuleSequence"]); CoursesAndModules course = new CoursesAndModules(courseName, moduleTitle, moduleSequence); courseList.Add(course); } // Close the database connection con.Close(); } return courseList; } } }
Salvare il file e chiudere l'editor di codice.
Aggiungere codice all'app Web per visualizzare i dati
L'applicazione è ora in grado di recuperare i dati dei corsi. A questo punto, aggiornare l'app per visualizzare i dati per l'utente.
In Cloud Shell passare alla
education/Pages
cartella .cd ~/education/Pages
Questa cartella contiene le pagine con estensione .cshtml e i file di codice che l'app Web usa per visualizzare le informazioni.
Usare l'editor di codice per aprire il file
Index.cshtml.cs
.code Index.cshtml.cs
Questo file contiene il codice che la pagina di indice esegue quando viene visualizzata. Il codice definisce la classe
CoursesAndModulesModel
. La pagina di indice usa questo modello per visualizzare i dettagli dei corsi e dei moduli. In questo file è necessario aggiungere il codice che usa un oggettoDataAccessController
per recuperare tali dati.using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CoursesWebApp.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace CoursesWebApp.Pages { public class CoursesAndModulesModel : PageModel { // TODO: Create a DataAccessController object // TODO: Create a collection for holding CoursesAndModules object public void OnGet() { // TODO: Retrieve the data using the DataAccessController object and populate the CoursesAndModules object } } }
In
Index.cshtml.cs
sostituire il commento// TODO: Create a DataAccessController object
con il codice seguente per creare un nuovoDataAccessController
oggetto .DataAccessController dac = new DataAccessController();
Sostituire il commento
// TODO: Create a collection for holding CoursesAndModules object
con il codice seguente.public List<CoursesAndModules> CoursesAndModules;
Nel metodo
OnGet
sostituire il commento// TODO: Retrieve the data using the DataAccessController object and populate the CoursesAndModules object
con il codice seguente. Questo codice usa l'oggettoDataAccessController
per popolare l'elenco con i dati provenienti dal database.CoursesAndModules = dac.GetAllCoursesAndModules().ToList();
Il file completato deve contenere il codice seguente.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CoursesWebApp.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace CoursesWebApp.Pages { public class CoursesAndModulesModel : PageModel { // Create a DataAccessController object DataAccessController dac = new DataAccessController(); // Create a collection for holding CoursesAndModules object public List<CoursesAndModules> CoursesAndModules; public void OnGet() { // Retrieve the data using the DataAccessController object and populate the CoursesAndModules object CoursesAndModules = dac.GetAllCoursesAndModules().ToList(); } } }
Salvare il file e chiudere l'editor di codice.
Usare l'editor di codice per aprire il file
Index.cshtml
.code Index.cshtml
Questo file contiene la logica di visualizzazione per la pagina di indice. Specifica
CoursesAndModulesModel
come origine dati. Il codice aggiunto consente di creare e popolare questo modello.La pagina usa dati HTML per visualizzare i dati dal modello. Attualmente la pagina visualizza solo le intestazioni della tabella. Il corpo della tabella (
<tbody>
) è vuoto.<h2>Courses and Modules</h2> <div> <table class="table"> <thead> <tr> <th> Course Name </th> <th> Modules </th> <th> Sequence </th> </tr> </thead> <tbody> <!-- TODO: Display the data from the CoursesAndModules collection --> </tbody> </table> </div>
Sostituire il commento
<!-- TODO: Display the data from the CoursesAndModules collection --\>
con il markup seguente.@foreach(var courseAndModule in Model.CoursesAndModules) { <tr> <td> @Html.DisplayFor(courseName => courseAndModule.CourseName) </td> <td> @Html.DisplayFor(moduleTitle => courseAndModule.ModuleTitle) </td> <td> @Html.DisplayFor(sequence => courseAndModule.Sequence) </td> </tr> }
Questo codice esegue l'iterazione attraverso le righe nel modello e restituisce i dati presenti in ogni campo.
Il file completato
Index.cshtml
deve contenere il codice seguente.@page @model CoursesAndModulesModel @{ ViewData["Title"] = "Home page"; } <h2>Courses and Modules</h2> <div> <table class="table"> <thead> <tr> <th> Course Name </th> <th> Modules </th> <th> Sequence </th> </tr> </thead> <tbody> @foreach(var courseAndModule in Model.CoursesAndModules) { <tr> <td> @Html.DisplayFor(courseName => courseAndModule.CourseName) </td> <td> @Html.DisplayFor(moduleTitle => courseAndModule.ModuleTitle) </td> <td> @Html.DisplayFor(sequence => courseAndModule.Sequence) </td> </tr> } </tbody> </table> </div>
Salvare il file e chiudere l'editor di codice.
Distribuire e testare l'app Web aggiornata
Con l'applicazione completamente configurata per recuperare e visualizzare i dati dei corsi per l'utente, è possibile distribuire la versione aggiornata.
In Cloud Shell tornare alla
education
cartella .cd ~/education
Eseguire i comandi seguenti per compilare e distribuire l'app Web aggiornata.
az webapp up \ --resource-group <rgn>[Sandbox resource group]</rgn> \ --name $WEBAPPNAME
Dopo la distribuzione della nuova app Web, selezionare il collegamento per l'app. L'app ora dovrebbe visualizzare un elenco di corsi e moduli con i dati archiviati nel database.