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

本教程介绍上一教程中通过搭建基架创建的 Razor 页面。

查看或下载示例。

“创建”、“删除”、“详细信息”和“编辑”页。

检查 Pages/Movies/Index.cshtml.cs 页面模型:

[!code-csharp]

Razor 页面派生自 PageModel按照约定,PageModel 派生的类称为 <PageName>Model此构造函数使用依赖关系注入MovieContext 添加到页。 所有已搭建基架的页面都遵循此模式。 请参阅异步代码,了解有关使用实体框架的异步编程的详细信息。

对页面发出请求时,OnGetAsync 方法向 Razor 页面返回影片列表。 在 Razor 页面上调用 OnGetAsyncOnGet 以初始化页面状态。 在这种情况下,OnGetAsync 将获得影片列表并显示出来。

OnGet 返回 voidOnGetAsync 返回 Task 时,不使用任何返回方法。 当返回类型是 IActionResultTask<IActionResult> 时,必须提供返回语句。 例如,Pages/Movies/Create.cshtml.cs OnPostAsync 方法:

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

@page
@model RazorPagesMovie.Pages.Movies.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.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 转换为 C# 或 Razor 特定标记。 @ 符号后跟 Razor 保留关键字时,它会转换为 Razor 特定标记,否则会转换为 C#。

@page Razor 指令将文件转换为一个 MVC 操作 —,这意味着它可以处理请求。 @page 必须是页面上的第一个 Razor 指令。 @page 是转换到 Razor 特定标记的一个示例。 有关详细信息,请参阅 Razor 语法

检查以下 HTML 帮助程序中使用的 Lambda 表达式:

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

DisplayNameFor HTML 帮助程序检查 Lambda 表达式中引用的 Title 属性来确定显示名称。 检查 Lambda 表达式(而非求值)。 这意味着当 modelmodel.Moviemodel.Movie[0]null 或为空时,不会存在任何访问冲突。 对 Lambda 表达式求值时(例如,使用 @Html.DisplayFor(modelItem => item.Title)),将求得该模型的属性值。

@model 指令

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@model 指令指定传递给 Razor 页面的模型类型。 在前面的示例中,@model 行使 PageModel 派生的类可用于 Razor 页面。 在页面上的 @Html.DisplayNameFor@Html.DisplayName HTML 帮助程序中使用该模型。

考虑下列代码:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

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

前面突出显示的代码是 Razor 转换为 C# 的一个示例。 {} 字符括住 C# 代码块。

PageModel 基类具有 ViewData 字典属性,可用于添加要传递到某个视图的数据。 可以使用键/值模式将对象添加到 ViewData 字典。 在前面的示例中,“Title”属性被添加到 ViewData 字典。

“Title”属性用于 Pages/Shared/_Layout.cshtml 文件。 以下标记显示 _Layout.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.*@ 为 Razor 注释。 与 HTML 注释不同 (<!-- -->),Razor 注释不会发送到客户端。

运行应用并测试项目中的链接(“主页”、“关于”、“联系人”、“创建”、“编辑”和“删除”)。 每个页面都设置有标题,可以在浏览器选项卡中看到标题。将某个页面加入书签时,标题用于该书签。 Pages/Index.cshtml 和 Pages/Movies/Index.cshtml 当前具有相同的标题,但可以修改它们以具有不同的值。

在 Pages/_ViewStart.cshtml 文件中设置 Layout 属性:

@{
    Layout = "_Layout";
}

前面的标记针对所有 Razor 文件将布局文件设置为 Pages 文件夹下的 Pages/_Layout.cshtml。 请参阅布局了解详细信息。

更新布局

更改 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"] - Movie</title>

查找 Pages/_Layout.cshtml 文件中的以下定位点元素。

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

将前面的元素替换为以下标记。

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

前面的定位点元素是一个标记帮助程序此处它是定位点标记帮助程序asp-page="/Movies/Index" 标记帮助程序属性和值可以创建指向 /Movies/Index Razor 页面的链接。

保存所做的更改,并通过单击“RpMovie”链接测试应用。 请参阅 GitHub 中的 _Layout.cshtml 文件。

“创建”页面模型

检查 Pages/Movies/Create.cshtml.cs 页面模型:

[!code-csharp]

OnGet 方法初始化页面所需的任何状态。 “创建”页没有任何要初始化的状态,因此返回 Page教程的后面部分将介绍 OnGet 方法初始化状态。 Page 方法创建用于呈现 Create.cshtml 页的 PageResult 对象。

Movie 属性使用 [BindProperty] 特性来选择加入模型绑定当“创建”表单发布表单值时,ASP.NET Core 运行时将发布的值绑定到 Movie 模型。

当页面发布表单数据时,运行 OnPostAsync 方法:

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

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

    return RedirectToPage("./Index");
}

如果不存在任何模型错误,将重新显示表单,以及发布的任何表单数据。 在发布表单前,可以在客户端捕获到大部分模型错误。 模型错误的一个示例是,发布的日期字段值无法转换为日期。 我们将在本教程后面的内容中讨论有关客户端验证和模型验证的更多信息。

如果不存在模型错误,将保存数据,并且浏览器会重定向到索引页。

创建 Razor 页面

检查 Pages/Movies/Create.cshtml Razor 页面文件:

@page
@model RazorPagesMovie.Pages.Movies.CreateModel

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

<h2>Create</h2>

<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-default" />
            </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 除外)创建 Razor 标记,如下所示:

<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)显示验证错误。 本系列后面的部分将更详细地讨论有关验证的信息。

标签标记帮助程序 (<label asp-for="Movie.Title" class="control-label"></label>) 生成标签描述和 Title 属性的 for 特性。

输入标记帮助程序 (<input asp-for="Movie.Title" class="form-control" />) 使用 DataAnnotations 属性并在客户端生成 jQuery 验证所需的 HTML 属性。

posted @ 2018-07-04 14:42  FH1004322  阅读(233)  评论(0)    收藏  举报