原文: 學習ASP.NET Core Razor 程式設計系列四——Asp.Net Core Razor清單模闆頁面 學習ASP.NET Core Razor 程式設計系列目錄 學習ASP.NET Core Razor 程式設計系列一 學習ASP.NET Core Razor 程式設計系列二——添加一個實體 學習ASP.NET Core Razor 程式設計系列三——建立資料表及建立項目基本頁面
本篇文章介紹上一篇文章中建立的書籍資訊管理系統中增删改查的四個Razor模闆頁面。
一、清單頁面。
我們首先來了解一下書籍清單頁面,這個頁面位置在 Pages/Books/Index.cshtml.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorMvcBooks.Models;
namespace RazorMvcBooks.Pages.Books
{
public class IndexModel : PageModel
{
private readonly RazorMvcBooks.Models.BookContext _context;
public IndexModel(RazorMvcBooks.Models.BookContext context)
{
_context = context;
}
public IList<Book> Book { get;set; }
public async Task OnGetAsync()
{
Book = await _context.Book.ToListAsync();
}
}
}
清單頁面IndexModel派生自 PageModel。 按照命名規則PageModel 的派生類一般命名為 <PageName>Model。 構造函數使用依賴關系注入的方式将 BookContext 添加到頁面。 所有通過上一文章中的方法建立的模闆頁面都是如此。
當Index頁面送出請求時,OnGetAsync 方法向 Razor 頁面傳回一個書籍清單。 在 Razor 頁面上調用 OnGetAsync 方法或 OnGet方法初始化頁面資料。 在本示例中,OnGetAsync 将資料庫中Book表中的所有書籍資訊,并以清單的形式顯示出來。
當 OnGet 方法傳回 void 或 OnGetAsync方法傳回 Task 時,不需要任何傳回語句。 當傳回類型是 IActionResult 或 Task<IActionResult> 時,必須提供傳回語句。
下面我們介紹一下有傳回的方法,例如 Pages/Movies/Create.cshtml.cs 頁面中的OnPostAsync方法,代碼如下:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Book.Add(Book);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
其次,我們來看看書籍清單頁面中的前端代碼,這個頁面位置在 Pages/Books/Index.cshtml,在Visual Studio 2017中使用滑鼠左鍵輕按兩下打開 頁面,代碼如下:
@page
@model RazorMvcBooks.Pages.Books.IndexModel
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Book[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Book[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Book[0].Author)
</th>
<th>
@Html.DisplayNameFor(model => model.Book[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Book) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Author)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Razor指令可以根據規則從 HTML 轉換為 C# 或 Razor 特定标記。 當在 @ 符号後跟 Razor 保留關鍵字時,它會轉換為 Razor 特定标記,如果不是Razor保留關鍵字,則會轉換為 C#。
@page Razor 指令将檔案轉換為一個 MVC 操作,這意味着它可以處理請求。 @page 必須是頁面上的第一個 Razor 指令。 @page 是轉換成 Razor 特定标記的一個示例。
請檢視下列HTML助手中使用的lambda表達式:
@Html.DisplayNameFor(model => model.Book[0].Name)
DisplayNameFor HTML輔助助手檢查 Lambda 表達式中引用的Name屬性來确定顯示名稱。 Lambda表達式是檢查而不是求值。 這意味着當 model、model.Book 或 model.Book[0] 為 null 或為空時,不會存在任何通路沖突。 當使用Html輔助助手取值輔助方法對 Lambda 表達式取值(例如,使用 @Html.DisplayFor(modelItem => item.Title)),将取得該實體的屬性值。
@model指令
@page
@model RazorMvcBooks.Pages.Books.IndexModel
@model 指令指定傳遞給 Razor 頁面的實體類型。在上面的示例中,@model 使 PageModel 派生的類IndexModel可用于 Razor 頁面。 在頁面上通過 @Html.DisplayNameFor 和 @Html.DisplayName HTML 輔助助手使用該實體。
ViewData 和布局
首先,我們看一下下面的布局代碼:
@page
@model RazorMvcBooks.Pages.Books.IndexModel
@{
ViewData["Title"] = "Index";
}
上面的代碼就是 Razor 代碼轉換為 C# 的一個示例。 大括号“{ }” 字元包覆 C# 代碼塊。
PageModel 基類具有 ViewData 字典屬性,可用于添加要傳遞到某個視圖的資料。 可以使用鍵/值模式将對象添加到 ViewData 字典。 在上面的示例中,“Title”屬性被添加到 ViewData 字典中。 “Title”屬性的在 Pages/_Layout.cshtml 檔案中使用。
你可以在Visual Studio 2017中打開 位于 Pages/_Layout.cshtml 檔案,我們來看看這個檔案中的前幾行,便可以發現 “Title”的使用。代碼如下。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorMvcBooks</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
@*Markup removed for brevity.*@
行 @*Markup removed for brevity.*@ 為 Razor 注釋。 與 HTML 注釋不同 (<!-- -->),Razor 注釋不會發送到用戶端。
在Visual Studio 2017 中按F5運作應用程式,在浏覽器測試項目中的連結(Home、About、Contact、Create、Edit和Delete)。你會發現在浏覽器中每個頁面的标題都是一樣的。當您将某個頁面添加到書簽時,标題用于這個書簽。 Pages/Index.cshtml 和 Pages/Books/Index.cshtml 目前具有相同的标題,但可以修改它們以具有不同的值。
我們可以在Visual Studio 2017中打開 位于 Pages/_ViewStart.cshtml 檔案,檢視其中的 Layout 屬性,如下代碼:
@{
Layout = "_Layout";
}
上面的标記将所有 Razor 頁面的布局設定為 Pages 檔案夾下的 Pages/_Layout.cshtml所定義的布局。
修改布局
第一步,我們要使用“書籍管理系統”來替換 Pages/_Layout.cshtml 檔案中的 <title> 元素中的RazorMvcBooks字元串。如下代碼。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] – 書籍管理系統</title>
第二步,在 Pages/_Layout.cshtml 檔案中的找到以下資料資訊:
<a asp-page="/Index" class="navbar-brand">RazorMvcBooks</a>
将上面的資料資訊替換為以下資料資訊:
<a asp-page="/Books/Index" class="navbar-brand">書籍管理系統</a>
上面的<a>元素是一個标記輔助助手。此處它是<a>标記輔助助手。asp-page="/Books/Index" 标記輔助助手屬性和值可以用來建立指向 /Books/Index Razor 頁面的連結。
儲存所做的修改,在Visual Studio 2017中按F5運作程式,在浏覽器中通過單擊“書籍管理系統”連結測試應用,如下圖。
