ASP.NET Core 中已搭建基架的 Razor 頁(yè)面
“創(chuàng)建”、“刪除”大年、“詳細(xì)信息”和“編輯”頁(yè)面
檢查 Pages/Movies/Index.cshtml.cs 頁(yè)面模型:
C#復(fù)制
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 RazorPagesMovie.Models;
namespace RazorPagesMovie.Pages.Movies
{
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
{
_context = context;
}
public IList<Movie> Movie { get;set; }
public async Task OnGetAsync()
{
Movie = await _context.Movie.ToListAsync();
}
}
}
Razor 頁(yè)面派生自 PageModel
滥朱。 按照約定鞍历,PageModel
派生的類(lèi)稱(chēng)為 <PageName>Model
乌询。 此構(gòu)造函數(shù)使用依賴(lài)關(guān)系注入將 RazorPagesMovieContext
添加到頁(yè)呀打。 所有已搭建基架的頁(yè)面都遵循此模式矢赁。 請(qǐng)參閱異步代碼,了解有關(guān)使用實(shí)體框架的異步編程的詳細(xì)信息贬丛。
對(duì)頁(yè)面發(fā)出請(qǐng)求時(shí)撩银,OnGetAsync
方法向 Razor 頁(yè)面返回影片列表。 在 Razor 頁(yè)面上調(diào)用 OnGetAsync
或 OnGet
以初始化頁(yè)面狀態(tài)瘫寝。 在這種情況下蜒蕾,OnGetAsync
將獲得影片列表并顯示出來(lái)。
當(dāng) OnGet
返回 void
或 OnGetAsync
返回 Task
時(shí)焕阿,不使用任何返回方法咪啡。 當(dāng)返回類(lèi)型是 IActionResult
或 Task<IActionResult>
時(shí),必須提供返回語(yǔ)句暮屡。 例如撤摸,Pages/Movies/Create.cshtml.cs OnPostAsync
方法:
C#復(fù)制
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
檢查 Pages/Movies/Index.cshtml Razor 頁(yè)面 :
CSHTML復(fù)制
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</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 轉(zhuǎn)換為 C# 或 Razor 特定標(biāo)記。 當(dāng) @
符號(hào)后跟 Razor 保留關(guān)鍵字時(shí)褒纲,它會(huì)轉(zhuǎn)換為 Razor 特定標(biāo)記准夷,否則會(huì)轉(zhuǎn)換為 C#。
@page
Razor 指令將文件轉(zhuǎn)換為一個(gè) MVC 操作莺掠,這意味著它可以處理請(qǐng)求衫嵌。 @page
必須是頁(yè)面上的第一個(gè) Razor 指令。 @page
是轉(zhuǎn)換到 Razor 特定標(biāo)記的一個(gè)示例彻秆。 有關(guān)詳細(xì)信息楔绞,請(qǐng)參閱 Razor 語(yǔ)法。
檢查以下 HTML 幫助程序中使用的 Lambda 表達(dá)式:
CSHTML復(fù)制
@Html.DisplayNameFor(model => model.Movie[0].Title))
DisplayNameFor
HTML 幫助程序檢查 Lambda 表達(dá)式中引用的 Title
屬性來(lái)確定顯示名稱(chēng)唇兑。檢查 Lambda 表達(dá)式(而非求值)酒朵。 這意味著當(dāng) model
、model.Movie
或 model.Movie[0]
為 null
或?yàn)榭諘r(shí)扎附,不會(huì)存在任何訪問(wèn)沖突蔫耽。 對(duì) Lambda 表達(dá)式求值時(shí)(例如,使用 @Html.DisplayFor(modelItem => item.Title)
)留夜,將求得該模型的屬性值匙铡。
@model 指令
CSHTML復(fù)制
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@model
指令指定傳遞給 Razor 頁(yè)面的模型類(lèi)型。 在前面的示例中碍粥,@model
行使 PageModel
派生的類(lèi)可用于 Razor 頁(yè)面慰枕。 在頁(yè)面上的 @Html.DisplayNameFor
和 @Html.DisplayFor
HTML 幫助程序中使用該模型。
布局頁(yè)
選擇菜單鏈接(“RazorPagesMovie” 即纲、“主頁(yè)” 和“隱私” )具帮。 每頁(yè)顯示相同的菜單布局。 菜單布局是在 Pages/Shared/_Layout.cshtml 文件中實(shí)現(xiàn)低斋。 打開(kāi) Pages/Shared/_Layout.cshtml 文件蜂厅。
布局模板使你能夠在一個(gè)位置指定網(wǎng)站的 HTML 容器布局,然后將它應(yīng)用到網(wǎng)站中的多個(gè)頁(yè)面膊畴。 查找 @RenderBody()
行掘猿。 RenderBody
是顯示所創(chuàng)建的全部頁(yè)面專(zhuān)用視圖的占位符,已包裝 在布局頁(yè)中唇跨。 例如稠通,如果選擇“隱私” 鏈接衬衬,Pages/Privacy.cshtml 視圖在 RenderBody
方法中呈現(xiàn)。
ViewData 和布局
考慮來(lái)自 Pages/Movies/Index.cshtml 文件中的以下代碼:
CSHTML復(fù)制
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
前面突出顯示的代碼是 Razor 轉(zhuǎn)換為 C# 的一個(gè)示例改橘。 {
和 }
字符括住 C# 代碼塊滋尉。
PageModel
基類(lèi)具有 ViewData
字典屬性,可用于添加要傳遞到某個(gè)視圖的數(shù)據(jù)飞主。 可以使用鍵/值模式將對(duì)象添加到 ViewData
字典狮惜。 在前面的示例中,“Title”屬性被添加到 ViewData
字典碌识。
“Title”屬性用于 Pages/Shared/_Layout.cshtml 文件 碾篡。 以下標(biāo)記顯示 _Layout.cshtml 文件的前幾行 。
CSHTML復(fù)制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorPagesMovie</title>
@*Markup removed for brevity.*@
行 @*Markup removed for brevity.*@
是不會(huì)出現(xiàn)在布局文件中的 Razor 注釋筏餐。 與 HTML 注釋不同 (``)开泽,Razor 注釋不會(huì)發(fā)送到客戶(hù)端。
更新布局
更改 Pages/Shared/_Layout.cshtml 文件中的 <title>
元素以顯示 Movie 而不是 RazorPagesMovie 魁瞪。
CSHTML復(fù)制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie</title>
在 Pages/Shared/_Layout.cshtml 文件中眼姐,查找以下定位點(diǎn)元素。
CSHTML復(fù)制
<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
將前面的元素替換為以下標(biāo)記佩番。
CSHTML復(fù)制
<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>
前面的定位點(diǎn)元素是一個(gè)標(biāo)記幫助程序众旗。 此處它是定位點(diǎn)標(biāo)記幫助程序。 asp-page="/Movies/Index"
標(biāo)記幫助程序?qū)傩院椭悼梢詣?chuàng)建指向 /Movies/Index
Razor 頁(yè)面的鏈接趟畏。 asp-area
屬性值為空贡歧,因此在鏈接中未使用區(qū)域。 有關(guān)詳細(xì)信息赋秀,請(qǐng)參閱區(qū)域利朵。
保存所做的更改,并通過(guò)單擊“RpMovie” 鏈接測(cè)試應(yīng)用猎莲。 如果遇到任何問(wèn)題绍弟,請(qǐng)參閱 GitHub 中的 _Layout.cshtml 文件。
測(cè)試其他鏈接(“主頁(yè)” 著洼、“RpMovie” 樟遣、“創(chuàng)建” 、“編輯” 和“刪除” )身笤。 每個(gè)頁(yè)面都設(shè)置有標(biāo)題豹悬,可以在瀏覽器選項(xiàng)卡中看到標(biāo)題。將某個(gè)頁(yè)面加入書(shū)簽時(shí)液荸,標(biāo)題用于該書(shū)簽瞻佛。
備注
可能無(wú)法在 Price
字段中輸入十進(jìn)制逗號(hào)。 若要使 jQuery 驗(yàn)證支持使用逗號(hào)(“,”)表示小數(shù)點(diǎn)的的非英語(yǔ)區(qū)域設(shè)置娇钱,以及支持非美國(guó)英語(yǔ)日期格式伤柄,必須執(zhí)行使應(yīng)用全球化的步驟绊困。 有關(guān)添加十進(jìn)制逗號(hào)的說(shuō)明,請(qǐng)參閱 GitHub 問(wèn)題 4076适刀。
在 Pages/_ViewStart.cshtml 文件中設(shè)置 Layout
屬性:
CSHTML復(fù)制
@{
Layout = "_Layout";
}
前面的標(biāo)記針對(duì)所有 Razor 文件將布局文件設(shè)置為 Pages 文件夾下的 Pages/Shared/_Layout.cshtml 秤朗。 請(qǐng)參閱布局了解詳細(xì)信息。
“創(chuàng)建”頁(yè)面模型
檢查 Pages/Movies/Create.cshtml.cs 頁(yè)面模型:
C#復(fù)制
// Unused usings removed.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;
namespace RazorPagesMovie.Pages.Movies
{
public class CreateModel : PageModel
{
private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
public CreateModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Movie Movie { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
OnGet
方法初始化頁(yè)面所需的任何狀態(tài)蔗彤。 “創(chuàng)建”頁(yè)沒(méi)有任何要初始化的狀態(tài),因此返回 Page
疯兼。 教程的后面部分將介紹 OnGet
方法初始化狀態(tài)然遏。 Page
方法創(chuàng)建用于呈現(xiàn) Create.cshtml 頁(yè)的 PageResult
對(duì)象。
Movie
屬性使用 [BindProperty]
特性來(lái)選擇加入模型綁定吧彪。 當(dāng)“創(chuàng)建”表單發(fā)布表單值時(shí)待侵,ASP.NET Core 運(yùn)行時(shí)將發(fā)布的值綁定到 Movie
模型。
當(dāng)頁(yè)面發(fā)布表單數(shù)據(jù)時(shí)姨裸,運(yùn)行 OnPostAsync
方法:
C#復(fù)制
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
如果不存在任何模型錯(cuò)誤秧倾,將重新顯示表單,以及發(fā)布的任何表單數(shù)據(jù)傀缩。 在發(fā)布表單前那先,可以在客戶(hù)端捕獲到大部分模型錯(cuò)誤。 模型錯(cuò)誤的一個(gè)示例是赡艰,發(fā)布的日期字段值無(wú)法轉(zhuǎn)換為日期售淡。 本教程后面討論了客戶(hù)端驗(yàn)證和模型驗(yàn)證。
如果不存在模型錯(cuò)誤慷垮,將保存數(shù)據(jù)揖闸,并且瀏覽器會(huì)重定向到索引頁(yè)。
創(chuàng)建 Razor 頁(yè)面
檢查 Pages/Movies/Create.cshtml Razor 頁(yè)面文件:
CSHTML復(fù)制
@page
@model RazorPagesMovie.Pages.Movies.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Movie.Title" class="control-label"></label>
<input asp-for="Movie.Title" class="form-control" />
<span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.ReleaseDate" class="control-label"></label>
<input asp-for="Movie.ReleaseDate" class="form-control" />
<span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Genre" class="control-label"></label>
<input asp-for="Movie.Genre" class="form-control" />
<span asp-validation-for="Movie.Genre" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Price" class="control-label"></label>
<input asp-for="Movie.Price" class="form-control" />
<span asp-validation-for="Movie.Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Visual Studio 以用于標(biāo)記幫助程序的特殊加粗字體顯示 <form method="post">
標(biāo)記:
<form method="post">
元素是一個(gè)表單標(biāo)記幫助程序料身。 表單標(biāo)記幫助程序會(huì)自動(dòng)包含防偽令牌汤纸。
基架引擎在模型中為每個(gè)字段(ID 除外)創(chuàng)建 Razor 標(biāo)記,如下所示:
CSHTML復(fù)制
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Movie.Title" class="control-label"></label>
<input asp-for="Movie.Title" class="form-control" />
<span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>
驗(yàn)證標(biāo)記幫助程序(<div asp-validation-summary
和 <span asp-validation-for
)顯示驗(yàn)證錯(cuò)誤芹血。 本系列后面的部分將更詳細(xì)地討論有關(guān)驗(yàn)證的信息贮泞。
標(biāo)簽標(biāo)記幫助程序 (<label asp-for="Movie.Title" class="control-label"></label>
) 生成標(biāo)簽描述和 Title
屬性的 for
特性。
輸入標(biāo)記幫助程序 (<input asp-for="Movie.Title" class="form-control">
) 使用 DataAnnotations 屬性并在客戶(hù)端生成 jQuery 驗(yàn)證所需的 HTML 屬性幔烛。