ASP.NET Core 中已搭建基架的 Razor 頁面

2019-04-17 08:56 更新

本教程介紹上一教程中通過搭建基架創(chuàng)建的 Razor 頁面。

查看或下載示例。

“創(chuàng)建”、“刪除”、“詳細信息”和“編輯”頁面

檢查 Pages/Movies/Index.cshtml.cs 頁面模型:

C#

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 頁面派生自 PageModel。 按照約定,PageModel 派生的類稱為 <PageName>Model。 此構(gòu)造函數(shù)使用依賴關(guān)系注入將 RazorPagesMovieContext 添加到頁。 所有已搭建基架的頁面都遵循此模式。請參閱異步代碼,了解有關(guān)使用實體框架的異步編程的詳細信息。

對頁面發(fā)出請求時,OnGetAsync 方法向 Razor 頁面返回影片列表。 在 Razor 頁面上調(diào)用 OnGetAsync 或 OnGet 以初始化頁面狀態(tài)。 在這種情況下,OnGetAsync 將獲得影片列表并顯示出來。

當 OnGet 返回 void 或 OnGetAsync 返回 Task 時,不使用任何返回方法。 當返回類型是 IActionResult 或 Task<IActionResult> 時,必須提供返回語句。 例如,Pages/Movies/Create.cshtml.cs OnPostAsync 方法:

C#

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 頁面:

CSHTML

@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 特定標記。 當 @ 符號后跟 Razor 保留關(guān)鍵字時,它會轉(zhuǎn)換為 Razor 特定標記,否則會轉(zhuǎn)換為 C#。

@page Razor 指令將文件轉(zhuǎn)換為一個 MVC 操作,這意味著它可以處理請求。 @page 必須是頁面上的第一個 Razor 指令。 @page 是轉(zhuǎn)換到 Razor 特定標記的一個示例。 有關(guān)詳細信息,請參閱 Razor 語法。

檢查以下 HTML 幫助程序中使用的 Lambda 表達式:

CSHTML

@Html.DisplayNameFor(model => model.Movie[0].Title))

DisplayNameFor HTML 幫助程序檢查 Lambda 表達式中引用的 Title 屬性來確定顯示名稱。 檢查 Lambda 表達式(而非求值)。 這意味著當 model、model.Movie 或 model.Movie[0] 為 null 或為空時,不會存在任何訪問沖突。 對 Lambda 表達式求值時(例如,使用 @Html.DisplayFor(modelItem => item.Title)),將求得該模型的屬性值。

@model 指令

CSHTML

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@model 指令指定傳遞給 Razor 頁面的模型類型。 在前面的示例中,@model 行使 PageModel 派生的類可用于 Razor 頁面。 在頁面上的 @Html.DisplayNameFor 和 @Html.DisplayFor HTML 幫助程序中使用該模型。

布局頁

選擇菜單鏈接(“RazorPagesMovie”、“主頁”和“隱私”)。 每頁顯示相同的菜單布局。 菜單布局是在 Pages/Shared/_Layout.cshtml 文件中實現(xiàn)。 打開 Pages/Shared/_Layout.cshtml 文件。

布局模板使你能夠在一個位置指定網(wǎng)站的 HTML 容器布局,然后將它應用到網(wǎng)站中的多個頁面。 查找 @RenderBody() 行。 RenderBody 是顯示所創(chuàng)建的全部頁面專用視圖的占位符,已包裝在布局頁中。 例如,如果選擇“隱私”鏈接,Pages/Privacy.cshtml 視圖在 RenderBody 方法中呈現(xiàn)。

ViewData 和布局

考慮來自 Pages/Movies/Index.cshtml 文件中的以下代碼:

CSHTML

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

前面突出顯示的代碼是 Razor 轉(zhuǎn)換為 C# 的一個示例。 { 和 } 字符括住 C# 代碼塊。

PageModel 基類具有 ViewData 字典屬性,可用于添加要傳遞到某個視圖的數(shù)據(jù)。 可以使用鍵/值模式將對象添加到 ViewData 字典。 在前面的示例中,“Title”屬性被添加到 ViewData 字典。

“Title”屬性用于 Pages/Shared/_Layout.cshtml 文件。 以下標記顯示 _Layout.cshtml 文件的前幾行。

CSHTML

<!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.*@ 是不會出現(xiàn)在布局文件中的 Razor 注釋。 與 HTML 注釋不同 (<!-- -->),Razor 注釋不會發(fā)送到客戶端。

更新布局

更改 Pages/Shared/_Layout.cshtml 文件中的 <title> 元素以顯示 Movie 而不是 RazorPagesMovie。

CSHTML

<!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 文件中,查找以下定位點元素。

CSHTML

<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>

將前面的元素替換為以下標記。

CSHTML

<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>

前面的定位點元素是一個標記幫助程序。 此處它是定位點標記幫助程序。 asp-page="/Movies/Index"標記幫助程序?qū)傩院椭悼梢詣?chuàng)建指向 /Movies/Index Razor 頁面的鏈接。 asp-area 屬性值為空,因此在鏈接中未使用區(qū)域。 有關(guān)詳細信息,請參閱區(qū)域

保存所做的更改,并通過單擊“RpMovie”鏈接測試應用。 如果遇到任何問題,請參閱 GitHub 中的 _Layout.cshtml 文件。

測試其他鏈接(“主頁”、“RpMovie”、“創(chuàng)建”、“編輯”和“刪除”)。 每個頁面都設置有標題,可以在瀏覽器選項卡中看到標題。將某個頁面加入書簽時,標題用于該書簽。

 備注

可能無法在 Price 字段中輸入十進制逗號。 若要使 jQuery 驗證支持使用逗號(“,”)表示小數(shù)點的的非英語區(qū)域設置,以及支持非美國英語日期格式,必須執(zhí)行使應用全球化的步驟。 有關(guān)添加十進制逗號的說明,請參閱 GitHub 問題 4076

在 Pages/_ViewStart.cshtml 文件中設置 Layout 屬性:

CSHTML

@{
    Layout = "_Layout";
}

前面的標記針對所有 Razor 文件將布局文件設置為 Pages 文件夾下的 Pages/Shared/_Layout.cshtml。 請參閱布局了解詳細信息。

“創(chuàng)建”頁面模型

檢查 Pages/Movies/Create.cshtml.cs 頁面模型:

C#

// 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 方法初始化頁面所需的任何狀態(tài)。 “創(chuàng)建”頁沒有任何要初始化的狀態(tài),因此返回 Page。 教程的后面部分將介紹 OnGet 方法初始化狀態(tài)。 Page 方法創(chuàng)建用于呈現(xiàn) Create.cshtml 頁的 PageResult 對象。

Movie 屬性使用 [BindProperty] 特性來選擇加入模型綁定。 當“創(chuàng)建”表單發(fā)布表單值時,ASP.NET Core 運行時將發(fā)布的值綁定到 Movie 模型。

當頁面發(fā)布表單數(shù)據(jù)時,運行 OnPostAsync 方法:

C#

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

如果不存在任何模型錯誤,將重新顯示表單,以及發(fā)布的任何表單數(shù)據(jù)。 在發(fā)布表單前,可以在客戶端捕獲到大部分模型錯誤。 模型錯誤的一個示例是,發(fā)布的日期字段值無法轉(zhuǎn)換為日期。 本教程后面討論了客戶端驗證和模型驗證。

如果不存在模型錯誤,將保存數(shù)據(jù),并且瀏覽器會重定向到索引頁。

創(chuàng)建 Razor 頁面

檢查 Pages/Movies/Create.cshtml Razor 頁面文件:

CSHTML

@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 以用于標記幫助程序的特殊加粗字體顯示 <form method="post"> 標記:

Create.cshtml 頁的 VS17 視圖

<form method="post"> 元素是一個表單標記幫助程序。 表單標記幫助程序會自動包含防偽令牌。

基架引擎在模型中為每個字段(ID 除外)創(chuàng)建 Razor 標記,如下所示:

CSHTML

<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 asp-validation-summary 和 <span asp-validation-for)顯示驗證錯誤。 本系列后面的部分將更詳細地討論有關(guān)驗證的信息。

標簽標記幫助程序 (<label asp-for="Movie.Title" class="control-label"></label>) 生成標簽描述和 Title 屬性的 for 特性。

輸入標記幫助程序 (<input asp-for="Movie.Title" class="form-control" />) 使用 DataAnnotations 屬性并在客戶端生成 jQuery 驗證所需的 HTML 屬性。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號