Esercizio: Connettere un'applicazione ASP.NET al database SQL di Azure

Completato

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:

High-level view of the application structure.

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

  1. Modificare la directory di lavoro nella education cartella .

    cd ~/education
    
  2. 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
    
  3. 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.

    The education web app running. Currently, no data is displayed.

    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.

  1. In Cloud Shell passare alla cartella education/Models.

    cd ~/education/Models
    

    Questa cartella contiene due file, CoursesAndModules.cs e DataAccessController.cs.

  2. 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
        }
    }
    
  3. 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.

  4. 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;
            }
        }
    }
    
  5. Salvare il file premendo CTRL+S e chiudere l'editor di codice premendo CTRL+Q.

  6. 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 oggetti CoursesAndModules.

    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;
            }
        }
    }
    
  7. Lasciare aperto l'editor di codice e passare al portale di Azure.

  8. Nel menu del portale di Azure selezionare Database SQL e quindi selezionare il database. Viene visualizzato il database SQL per coursedatabaseNNN.

  9. Nel riquadro del menu a sinistra, in Impostazioni selezionare Stringhe di connessione. Copiare la stringa di connessione ADO.NET negli Appunti.

    The connection string pane in the Azure portal.

  10. 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 valore azuresql. 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;";
    
  11. Dopo il commento //TODO: Connect to the database, sostituire l'istruzione using 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.

  12. 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 nella dbo.StudyPlan tabella.

  13. 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.

  14. 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 oggetto CoursesAndModules. Questo oggetto viene quindi aggiunto a un elenco.

  15. 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;
            }
        }
    }
    
  16. 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.

  1. 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.

  2. 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 oggetto DataAccessController 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
            }
        }
    }
    
  3. In Index.cshtml.cssostituire il commento // TODO: Create a DataAccessController object con il codice seguente per creare un nuovo DataAccessController oggetto .

    DataAccessController dac = new DataAccessController();
    
  4. Sostituire il commento // TODO: Create a collection for holding CoursesAndModules object con il codice seguente.

    public List<CoursesAndModules> CoursesAndModules;
    
  5. 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'oggetto DataAccessController 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();
            }
        }
    }
    
  6. Salvare il file e chiudere l'editor di codice.

  7. 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>
    
  8. 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>
    
  9. 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.

  1. In Cloud Shell tornare alla education cartella .

    cd ~/education
    
  2. Eseguire i comandi seguenti per compilare e distribuire l'app Web aggiornata.

    az webapp up \
        --resource-group <rgn>[Sandbox resource group]</rgn> \
        --name $WEBAPPNAME
    
  3. 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.

    Screenshot of the education web app running, showing the data.