Упражнение. Подключение приложения ASP.NET к Базе данных SQL Azure

Завершено

Теперь база данных создана. Теперь вы можете настроить и развернуть веб-приложение, которое академические консультанты могут использовать для обсуждения курсов и планов обучения с учащимися. Приложение использует System.Data.SqlClient библиотеку для получения и отображения сведений о курсах и модулях, которые учащийся должен пройти для завершения курса.

Чтобы сэкономить время, мы используем предварительно существующее веб-приложение и покажем, как добавить код, который подключает это приложение к базе данных. На следующей схеме показаны основные компоненты этого приложения:

High-level view of the application structure.

Чтобы настроить веб-приложение, выполните следующие действия.

  • создадите класс, содержащий название курса, название модуля и порядок выполнения;
  • создадите класс контроллера доступа к данным для получения сведений из базы данных;
  • измените код страницы индексов в веб-приложении для создания объекта контроллера доступа к данным и получения данных;
  • измените страницу индексов для отображения данных.

Развертывание и запуск существующего веб-приложения

  1. Измените рабочий каталог на папку education .

    cd ~/education
    
  2. Выполните следующие команды, чтобы выполнить сборку исходного веб-приложения и развернуть его:

    WEBAPPNAME=educationapp-$RANDOM
    az webapp up \
        --resource-group <rgn>[Sandbox resource group]</rgn> \
        --location centralus \
        --sku F1 \
        --name $WEBAPPNAME
    
  3. При развертывании веб-приложения выходные данные отображают App_url с URL-адресом веб-сайта. Откройте этот сайт на новой вкладке.

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

    Вам необходимо, чтобы в веб-приложении выводился список курсов и модулей, из которых состоит определенный курс. В настоящее время приложение не получает и не отображает эти данные. Итак, вам нужно обновить код, чтобы получить данные из базы данных и отобразить их.

Добавление в веб-приложение кода для получения данных

Давайте добавим в приложение код, получающий из базы данных сведения о курсах.

  1. В Cloud Shell перейдите в папку education/Models .

    cd ~/education/Models
    

    Эта папка содержит два файла и CoursesAndModules.csDataAccessController.cs.

  2. Откройте файл с помощью редактора CoursesAndModules.cs кода.

    code CoursesAndModules.cs
    

    Этот файл содержит пустой класс 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. Замените комментарий // TODO: Define the CourseName, ModuleTitle, and Sequence read-only properties следующим кодом.

    public string CourseName { get; }
    public string ModuleTitle { get; }
    public int Sequence { get; }
    

    Этот код определяет набор полей только для чтения, содержащих данные для каждой строки, отображаемой веб-приложением.

  4. Замените комментарий // TODO: Create a constructor that initializes the fields behind the properties следующим конструктором:

    public CoursesAndModules(string courseName, string moduleTitle, int sequence)
    {
        this.CourseName = courseName;
        this.ModuleTitle = moduleTitle;
        this.Sequence = sequence;
    }
    

    Этот конструктор заполняет поля отображаемыми данными. В полном виде код файла должен выглядеть так:

    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. Сохраните файл, нажав CTRL+S, и закройте редактор кода, нажав CTRL+Q.

  6. Откройте файл с помощью редактора DataAccessController.cs кода.

    code DataAccessController.cs
    

    Файл содержит класс DataAccessController. Этот класс содержит логику доступа к данным для подключения к базе данных и получения данных курса и модуля. Он заполняет список объектов данными 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. Не закрывая редактор кода, перейдите на портал Azure.

  8. В меню портала Microsoft Azure выберите Базы данных SQL, а затем — свою базу данных. Появится База данных SQL для coursedatabaseNNN.

  9. На панели меню слева выберите Параметры, а затем — Строки подключения. Скопируйте строку подключения ADO.NET в буфер обмена.

    The connection string pane in the Azure portal.

  10. Вернитесь в редактор кода. Замените значение переменной connectionString содержимым буфера обмена. В строке подключения найдите текст User ID со значением azuresql. Замените текст {your_password} паролем для этой учетной записи.

    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. После комментария //TODO: Connect to the database замените закомментированный оператор using следующим кодом:

    using (SqlConnection con = new SqlConnection(connectionString))
    

    Этот код создает объект SqlConnection, который устанавливает подключение к базе данных с использованием указанной строки подключения.

  12. Замените комментарий // TODO: 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;
    

    Объект SqlCommand содержит инструкцию Transact-SQL (T-SQL), которая извлекает данные для всех курсов и модулей. Он объединяет их с помощью сведений dbo.StudyPlan в таблице.

  13. Замените комментарий // TODO: Execute the query следующим кодом.

    con.Open();
    SqlDataReader rdr = cmd.ExecuteReader();
    

    Эти инструкции открывают подключение к базе данных и запускают инструкцию T-SQL. С помощью объекта SqlDataReader можно получать результаты по одной строке за раз.

  14. Замените комментарий // TODO: 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);
    }
    

    Этот блок перебирает строки, возвращаемые в объекте SqlDataReader. Он извлекает данные из полей каждой строки и заполняет ими новый объект CoursesAndModules. Затем этот объект добавляется в список.

  15. Замените комментарий // TODO: Close the database connection следующим оператором:

    con.Close();
    

    Этот оператор закрывает подключение к базе данных и высвобождает выделенные ресурсы.

    В полном виде класс должен содержать следующий код со строкой подключения к вашей базе данных:

    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. Сохраните файл и закройте редактор Code.

Добавление в веб-приложение кода для отображения данных

Теперь приложение может извлекать сведения о курсах. Измените его так, чтобы в нем выводились сведения о курсах.

  1. В Cloud Shell перейдите в папку education/Pages .

    cd ~/education/Pages
    

    Эта папка содержит страницы CSHTML и файлы кода, которые веб-приложение использует для отображения данных.

  2. Откройте файл с помощью редактора Index.cshtml.cs кода.

    code Index.cshtml.cs
    

    Этот файл содержит код, который выполняется при отображении страницы индексов. В нем определен класс CoursesAndModulesModel. Страница индекса использует эту модель для отображения сведений о курсах и модулях. В файл нужно добавить код, использующий объект DataAccessController для получения данных.

    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. В Index.cshtml.csокне замените комментарий // TODO: Create a DataAccessController object следующим кодом, чтобы создать новый DataAccessController объект.

    DataAccessController dac = new DataAccessController();
    
  4. Замените комментарий // TODO: Create a collection for holding CoursesAndModules object следующим кодом.

    public List<CoursesAndModules> CoursesAndModules;
    
  5. В методе OnGet замените комментарий // TODO: Retrieve the data using the DataAccessController object and populate the CoursesAndModules object приведенным ниже кодом. В нем объект DataAccessController используется для заполнения списка данными из базы данных.

    CoursesAndModules = dac.GetAllCoursesAndModules().ToList();
    

    Код готового файла должен выглядеть так:

    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. Сохраните файл и закройте редактор кода.

  7. Откройте файл Index.cshtmlс помощью редактора кода.

    code Index.cshtml
    

    Этот файл содержит логику отображения данных для страницы индексов. В качестве источника данных указан объект CoursesAndModulesModel. Добавленный вами код создает и заполняет эту модель.

    Данные из модели отображаются на странице в формате HTML. В настоящее время на странице выводятся только заголовки таблиц. Их содержимое (<tbody>) отсутствует.

    <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. Замените комментарий <!-- TODO: Display the data from the CoursesAndModules collection --\> следующей разметкой:

    @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>
    }
    

    Этот код перебирает строки модели и выводит данные в каждом поле.

    Завершенный Index.cshtml файл должен содержать следующий код.

    @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. Сохраните файл и закройте редактор кода.

Развертывание и тестирование измененного веб-приложения

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

  1. В Cloud Shell вернитесь в папку education .

    cd ~/education
    
  2. Выполните следующие команды, чтобы выполнить сборку обновленного веб-приложения и развернуть его.

    az webapp up \
        --resource-group <rgn>[Sandbox resource group]</rgn> \
        --name $WEBAPPNAME
    
  3. После развертывания нового веб-приложения выберите ссылку приложения. Теперь в нем должен отображаться список курсов и модулей на основе сведений из базы данных.

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