練習 - 新增 Razor 頁面

已完成

您已在上一個單元中取得 Contoso Pizza 專案的原始程式碼,然後在首頁進行一些簡單的變更。 您會在本單元中,將新的 Razor 頁面新增至此專案。

建立披薩清單頁面

若要建立新的 Razor 頁面,您將使用 .NET CLI。

  1. 因為 dotnet watch 命令會封鎖終端,請以滑鼠右鍵按一下 [總管] 中的 [ContosoPizza] 資料夾,然後選取 [在整合式終端中開啟],以開啟另一個終端。

  2. 在新的終端視窗中,輸入下列命令:

    dotnet new page --name PizzaList --namespace ContosoPizza.Pages --output Pages
    

    上述命令會:

    • ContosoPizza.Pages 命名空間中建立這兩個檔案:
      • PizzaList.cshtml- Razor 頁面
      • PizzaList.cshtml.cs- 隨附的 PageModel 類別
    • 將這兩個檔案儲存於專案的 Pages 子目錄中。
  3. 在 Pages/PizzaList.cshtml 中,在 @{ } 程式碼區塊中新增下列程式碼:

    ViewData["Title"] = "Pizza List 🍕";
    

    這會設定頁面的 <title> 元素。

  4. 在檔案結尾處,新增下列程式碼:

    <h1>Pizza List 🍕</h1>
    
    <!-- New Pizza form will go here -->
    
    <!-- List of pizzas will go here -->
    

    這會將標題新增至頁面,以及為稍後將新增功能的兩個 HTML 註解預留位置。

  5. 儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。

  6. 返回執行 dotnet watch 的終端,然後選取 Ctrl+R 以重新載入應用程式並偵測新的檔案。

將 [披薩清單] 頁面新增至導覽功能表

這是測試頁面的好時機,但無法連線到瀏覽器中的頁面,因為它在瀏覽功能表中尚未連結。 您現在將連結它。

  1. 開啟 Pages/Shared/_Layout.cshtml。

  2. 在類別為 navbar-nav (從第 21 行開始) 的 <ul> 元素中,請注意內含 [首頁] 和 [隱私權] 頁面連結的 <li> 元素。 在包含 [隱私權] 連結的 <li> 元素後面,將下列程式碼新增至清單結尾:

    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="" asp-page="/PizzaList">Pizza List 🍕</a>
    </li>
    

    這會將 PizzaList 頁面的連結新增至導覽功能表。

  3. 儲存檔案。 具有應用程式的瀏覽器索引標籤會自動重新整理以顯示變更。 如果使用的是 GitHub Codespaces,檔案會自動儲存,但您必須手動重新整理瀏覽器索引標籤。

  4. 選取導覽功能表中的 [披薩清單🍕] 連結。 即會出現披薩清單頁面。

使用相依性插入容器註冊 PizzaService 類別

[披薩清單] 頁面取決於要擷取披薩清單 PizzaService 的物件。 您將使用相依性插入,將 PizzaService 物件提供給頁面。 首先,向容器註冊 PizzaService 類別。

  1. 開啟 Program.cs

  2. 在將服務新增至容器的區段中,新增下列程式碼:

    builder.Services.AddScoped<PizzaService>();
    

    此程式碼會向相依性插入容器註冊 PizzaService 類別。 AddScoped 方法表示應該為每個 HTTP 要求建立新的 PizzaService 物件。 現在可將 PizzaService 插入任何 Razor 頁面。

  3. 儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。

顯示披薩清單

讓我們修改披薩清單頁面的 PageModel 類別,以從 PizzaService 物件擷取披薩清單,並將其儲存在屬性中。

  1. 開啟 [Pages/PizzaList.cshtml.cs]。

  2. 將下列 using 陳述式新增至檔案頂端:

    using ContosoPizza.Models;
    using ContosoPizza.Services;
    

    這些陳述式會匯入您將在頁面中使用的 PizzaPizzaService 型別。

  3. ContosoPizza.Pages 命名空間區塊內,以下列程式碼取代整個 PizzaListModel 類別:

    public class PizzaListModel : PageModel
    {
        private readonly PizzaService _service;
        public IList<Pizza> PizzaList { get;set; } = default!;
    
        public PizzaListModel(PizzaService service)
        {
            _service = service;
        }
    
        public void OnGet()
        {
            PizzaList = _service.GetPizzas();
        }
    }
    

    在上述程式碼中:

    • 會建立名為 _service 的私人唯讀 PizzaService。 此變數會保存 PizzaService 物件的參考。
      • readonly 關鍵字表示在建構函式中設定之後,就無法變更 _service 變數的值。
    • 已定義 PizzaList 屬性來保存披薩清單。
      • IList<Pizza> 型別表示 PizzaList 屬性會保存 Pizza 物件清單。
      • 已將 PizzaList 初始化為 default!,以向編譯器指出將在稍後初始化,因此不需要 Null 安全性檢查。
    • 建構函式會接受 PizzaService 物件。
      • PizzaService 物件是由相依性插入所提供。
    • 已定義 OnGet 方法,以從 PizzaService 物件擷取披薩清單,並將其儲存在 PizzaList 屬性中。

    提示

    如果您需要了解 Null 安全性的協助,請參閱 C# 中的 Null 安全性

  4. 儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。

  5. 返回執行 dotnet watch 的終端,然後按 [Ctrl+R] 以重新載入具有已註冊服務的應用程式,以及 PizzaListModel 的新建構函式。

顯示披薩清單

現在該頁面可以存取披薩清單,您將會使用該清單在頁面上顯示披薩。

  1. 開啟 [Pages/PizzaList.cshtml]。

  2. 以下列程式碼取代 <!-- List of pizzas will go here --> 註解:

    <table class="table mt-5">
        <thead>
            <tr>
                <th scope="col">Name</th>
                <th scope="col">Price</th>
                <th scope="col">Size</th>
                <th scope="col">Gluten Free</th>
                <th scope="col">Delete</th>
            </tr>
        </thead>
        <tbody>
        @foreach (var pizza in Model.PizzaList)
        {
            <tr>
                <td>@pizza.Name</td>
                <td>@($"{pizza.Price:C}")</td>
                <td>@pizza.Size</td>
                <td>@(pizza.IsGlutenFree ? "✔️" : string.Empty)</td>
                <td>
                    <form method="post" asp-page-handler="Delete" asp-route-id="@pizza.Id">
                        <button class="btn btn-danger">Delete</button>
                    </form>
                </td>
            </tr>
        }
        </tbody>
    </table>
    

    在上述程式碼中:

    • 會建立 <table> 元素,以顯示披薩清單。
    • 會建立 <thead> 元素來保存資料表標頭。
    • <tbody> 內的 @foreach 陳述式會逐一查看披薩清單。
      • Model 屬性是指在程式碼後置檔案中建立的 PizzaListModel 物件。
      • PizzaList 屬性是指在程式碼後置檔案中定義的 PizzaList 屬性。
    • @foreach 陳述式的每次反覆運算都會建立 <tr> 元素來保存披薩資料:
      • Razor 語法可用來顯示 <td> 元素中的披薩資料。 此語法是用來顯示在 pizza 變數中儲存之 Pizza 物件的屬性。
      • 使用 C# 字串內插補點將 Price 格式化。
      • 三元運算式會用來將 IsGlutenFree 屬性的值顯示為「✔️」或空白儲存格。
      • 會建立表單來刪除披薩。
        • asp-page-handler 屬性表示應將表單提交至 Delete 程式碼後置檔案中的處理常式。 您將在稍後的單元中建立該處理常式。
        • asp-route-id 屬性表示應將 Pizza 物件的 Id 屬性傳遞至 Delete 處理常式。
  3. 儲存檔案。 [披薩清單] 頁面會在瀏覽器中重新整理,並顯示披薩清單。 如果使用的是 GitHub Codespaces,檔案會自動儲存,但您必須手動重新整理瀏覽器索引標籤。

[披薩清單] 頁面的螢幕擷取畫面,內含工作清單。

讚! 您已建立 Razor 頁面,此頁面會顯示披薩清單。 在下一個單元中,您將了解標籤協助程式和頁面處理常式的相關資訊。