練習 - 新增 Razor 頁面
您已在上一個單元中取得 Contoso Pizza 專案的原始程式碼,然後在首頁進行一些簡單的變更。 您會在本單元中,將新的 Razor 頁面新增至此專案。
建立披薩清單頁面
若要建立新的 Razor 頁面,您將使用 .NET CLI。
因為
dotnet watch
命令會封鎖終端,請以滑鼠右鍵按一下 [總管] 中的 [ContosoPizza] 資料夾,然後選取 [在整合式終端中開啟],以開啟另一個終端。在新的終端視窗中,輸入下列命令:
dotnet new page --name PizzaList --namespace ContosoPizza.Pages --output Pages
上述命令會:
- 在
ContosoPizza.Pages
命名空間中建立這兩個檔案:- PizzaList.cshtml- Razor 頁面
- PizzaList.cshtml.cs- 隨附的
PageModel
類別
- 將這兩個檔案儲存於專案的 Pages 子目錄中。
- 在
在 Pages/PizzaList.cshtml 中,在
@{ }
程式碼區塊中新增下列程式碼:ViewData["Title"] = "Pizza List 🍕";
這會設定頁面的
<title>
元素。在檔案結尾處,新增下列程式碼:
<h1>Pizza List 🍕</h1> <!-- New Pizza form will go here --> <!-- List of pizzas will go here -->
這會將標題新增至頁面,以及為稍後將新增功能的兩個 HTML 註解預留位置。
儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。
返回執行
dotnet watch
的終端,然後選取 Ctrl+R 以重新載入應用程式並偵測新的檔案。
將 [披薩清單] 頁面新增至導覽功能表
這是測試頁面的好時機,但無法連線到瀏覽器中的頁面,因為它在瀏覽功能表中尚未連結。 您現在將連結它。
開啟 Pages/Shared/_Layout.cshtml。
在類別為
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 頁面的連結新增至導覽功能表。
儲存檔案。 具有應用程式的瀏覽器索引標籤會自動重新整理以顯示變更。 如果使用的是 GitHub Codespaces,檔案會自動儲存,但您必須手動重新整理瀏覽器索引標籤。
選取導覽功能表中的 [披薩清單🍕] 連結。 即會出現披薩清單頁面。
使用相依性插入容器註冊 PizzaService 類別
[披薩清單] 頁面取決於要擷取披薩清單 PizzaService
的物件。 您將使用相依性插入,將 PizzaService
物件提供給頁面。 首先,向容器註冊 PizzaService
類別。
開啟 Program.cs。
在將服務新增至容器的區段中,新增下列程式碼:
builder.Services.AddScoped<PizzaService>();
此程式碼會向相依性插入容器註冊
PizzaService
類別。AddScoped
方法表示應該為每個 HTTP 要求建立新的PizzaService
物件。 現在可將PizzaService
插入任何 Razor 頁面。儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。
顯示披薩清單
讓我們修改披薩清單頁面的 PageModel
類別,以從 PizzaService
物件擷取披薩清單,並將其儲存在屬性中。
開啟 [Pages/PizzaList.cshtml.cs]。
將下列
using
陳述式新增至檔案頂端:using ContosoPizza.Models; using ContosoPizza.Services;
這些陳述式會匯入您將在頁面中使用的
Pizza
和PizzaService
型別。在
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 安全性。
- 會建立名為
儲存檔案。 如果您使用 GitHub Codespaces,檔案會自動儲存。
返回執行
dotnet watch
的終端,然後按 [Ctrl+R] 以重新載入具有已註冊服務的應用程式,以及PizzaListModel
的新建構函式。
顯示披薩清單
現在該頁面可以存取披薩清單,您將會使用該清單在頁面上顯示披薩。
開啟 [Pages/PizzaList.cshtml]。
以下列程式碼取代
<!-- 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
處理常式。
- Razor 語法可用來顯示
- 會建立
儲存檔案。 [披薩清單] 頁面會在瀏覽器中重新整理,並顯示披薩清單。 如果使用的是 GitHub Codespaces,檔案會自動儲存,但您必須手動重新整理瀏覽器索引標籤。
讚! 您已建立 Razor 頁面,此頁面會顯示披薩清單。 在下一個單元中,您將了解標籤協助程式和頁面處理常式的相關資訊。