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

本文内容

作者:Rick Anderson

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

查看或下载示例代码如何下载)。

查看或下载示例代码如何下载)。

“创建”、“删除”、“详细信息”和“编辑”页面The Create, Delete, Details, and Edit pages

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

  1. // Unused usings removed.
  2. using Microsoft.AspNetCore.Mvc.RazorPages;
  3. using Microsoft.EntityFrameworkCore;
  4. using RazorPagesMovie.Models;
  5. using System.Collections.Generic;
  6. using System.Threading.Tasks;
  7. namespace RazorPagesMovie.Pages.Movies
  8. {
  9. public class IndexModel : PageModel
  10. {
  11. private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
  12. public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
  13. {
  14. _context = context;
  15. }
  16. public IList<Movie> Movie { get;set; }
  17. public async Task OnGetAsync()
  18. {
  19. Movie = await _context.Movie.ToListAsync();
  20. }
  21. }
  22. }

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

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

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

  1. public async Task<IActionResult> OnPostAsync()
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return Page();
  6. }
  7. _context.Movie.Add(Movie);
  8. await _context.SaveChangesAsync();
  9. return RedirectToPage("./Index");
  10. }
  11. }

检查 Pages/Movies/Index.cshtml Razor 页面 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <table class="table">
  11. <thead>
  12. <tr>
  13. <th>
  14. @Html.DisplayNameFor(model => model.Movie[0].Title)
  15. </th>
  16. <th>
  17. @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
  18. </th>
  19. <th>
  20. @Html.DisplayNameFor(model => model.Movie[0].Genre)
  21. </th>
  22. <th>
  23. @Html.DisplayNameFor(model => model.Movie[0].Price)
  24. </th>
  25. <th></th>
  26. </tr>
  27. </thead>
  28. <tbody>
  29. @foreach (var item in Model.Movie) {
  30. <tr>
  31. <td>
  32. @Html.DisplayFor(modelItem => item.Title)
  33. </td>
  34. <td>
  35. @Html.DisplayFor(modelItem => item.ReleaseDate)
  36. </td>
  37. <td>
  38. @Html.DisplayFor(modelItem => item.Genre)
  39. </td>
  40. <td>
  41. @Html.DisplayFor(modelItem => item.Price)
  42. </td>
  43. <td>
  44. <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
  45. <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
  46. <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
  47. </td>
  48. </tr>
  49. }
  50. </tbody>
  51. </table>

Razor 可以从 HTML 转换为 C# 或 Razor 特定标记。@ 符号后跟 Razor 保留关键字时,它会转换为 Razor 特定标记,否则会转换为 C#。

@page 指令The @page directive

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

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

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

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

@model 指令The @model directive

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel

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

布局页The layout page

选择菜单链接(“RazorPagesMovie” 、“主页” 和“隐私” )。每页显示相同的菜单布局。菜单布局是在 Pages/Shared/_Layout.cshtml 文件中实现。打开 Pages/Shared/_Layout.cshtml 文件。

布局模板允许 HTML 容器具有如下布局:

  • 在一个位置指定。
  • 应用于站点中的多个页面。

查找 @RenderBody() 行。RenderBody 是显示全部页面专用视图的占位符,已包装 在布局页中。例如,选择“隐私” 链接后,Pages/Privacy.cshtml 视图在 RenderBody 方法中呈现。

ViewData 和布局ViewData and layout

考虑来自 Pages/Movies/Index.cshtml 文件中的以下标记:

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }

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

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

"Title" 属性用于 Pages/Shared/_Layout.cshtml 文件 。以下标记显示 _Layout.cshtml 文件的前几行 。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>@ViewData["Title"] - RazorPagesMovie</title>
  7. @*Markup removed for brevity.*@

@Markup removed for brevity.@ 为 Razor 注释。与 HTML 注释不同 (<!— —>),Razor 注释不会发送到客户端。

更新布局Update the layout

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>@ViewData["Title"] - Movie</title>

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

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

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

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

前面的定位点元素是一个标记帮助程序此处它是定位点标记帮助程序asp-page="/Movies/Index" 标记帮助程序属性和值可以创建指向 /Movies/Index Razor 页面的链接。asp-area 属性值为空,因此在链接中未使用区域。有关详细信息,请参阅区域

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

测试其他链接(“主页” 、“RpMovie” 、“创建” 、“编辑” 和“删除” )。每个页面都设置有标题,可以在浏览器选项卡中看到标题。将某个页面加入书签时,标题用于该书签。

备注

可能无法在 Price 字段中输入十进制逗号。若要使 jQuery 验证支持使用逗号(“,”)表示小数点的的非英语区域设置,以及支持非美国英语日期格式,必须执行使应用全球化的步骤。有关添加十进制逗号的说明,请参阅 GitHub 问题 4076

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

  1. @{
  2. Layout = "_Layout";
  3. }

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

“创建”页面模型The Create page model

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

  1. using Microsoft.AspNetCore.Mvc;
  2. using Microsoft.AspNetCore.Mvc.RazorPages;
  3. using RazorPagesMovie.Models;
  4. using System;
  5. using System.Threading.Tasks;
  6. namespace RazorPagesMovie.Pages.Movies
  7. {
  8. public class CreateModel : PageModel
  9. {
  10. private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
  11. public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
  12. {
  13. _context = context;
  14. }
  15. public IActionResult OnGet()
  16. {
  17. return Page();
  18. }
  19. [BindProperty]
  20. public Movie Movie { get; set; }
  21. public async Task<IActionResult> OnPostAsync()
  22. {
  23. if (!ModelState.IsValid)
  24. {
  25. return Page();
  26. }
  27. _context.Movie.Add(Movie);
  28. await _context.SaveChangesAsync();
  29. return RedirectToPage("./Index");
  30. }
  31. }
  32. }

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

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

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

  1. public async Task<IActionResult> OnPostAsync()
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return Page();
  6. }
  7. _context.Movie.Add(Movie);
  8. await _context.SaveChangesAsync();
  9. return RedirectToPage("./Index");
  10. }

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

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

创建 Razor 页面The Create Razor Page

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

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.CreateModel
  3. @{
  4. ViewData["Title"] = "Create";
  5. }
  6. <h1>Create</h1>
  7. <h4>Movie</h4>
  8. <hr />
  9. <div class="row">
  10. <div class="col-md-4">
  11. <form method="post">
  12. <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  13. <div class="form-group">
  14. <label asp-for="Movie.Title" class="control-label"></label>
  15. <input asp-for="Movie.Title" class="form-control" />
  16. <span asp-validation-for="Movie.Title" class="text-danger"></span>
  17. </div>
  18. <div class="form-group">
  19. <label asp-for="Movie.ReleaseDate" class="control-label"></label>
  20. <input asp-for="Movie.ReleaseDate" class="form-control" />
  21. <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
  22. </div>
  23. <div class="form-group">
  24. <label asp-for="Movie.Genre" class="control-label"></label>
  25. <input asp-for="Movie.Genre" class="form-control" />
  26. <span asp-validation-for="Movie.Genre" class="text-danger"></span>
  27. </div>
  28. <div class="form-group">
  29. <label asp-for="Movie.Price" class="control-label"></label>
  30. <input asp-for="Movie.Price" class="form-control" />
  31. <span asp-validation-for="Movie.Price" class="text-danger"></span>
  32. </div>
  33. <div class="form-group">
  34. <input type="submit" value="Create" class="btn btn-primary" />
  35. </div>
  36. </form>
  37. </div>
  38. </div>
  39. <div>
  40. <a asp-page="Index">Back to List</a>
  41. </div>
  42. @section Scripts {
  43. @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  44. }

Visual Studio 以用于标记帮助程序的特殊加粗字体显示以下标记:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Create.cshtml 页的 VS17 视图

以下标记帮助程序显示在前面的标记中:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

Visual Studio 以用于标记帮助程序的特殊加粗字体显示以下标记:

  • <form method="post">
  • <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  • <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>

<form method="post"> 元素是一个表单标记帮助程序表单标记帮助程序会自动包含防伪令牌

基架引擎在模型中为每个字段(ID 除外)创建 Razor 标记,如下所示:

  1. <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  2. <div class="form-group">
  3. <label asp-for="Movie.Title" class="control-label"></label>
  4. <input asp-for="Movie.Title" class="form-control" />
  5. <span asp-validation-for="Movie.Title" class="text-danger"></span>
  6. </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 属性。

有关标记帮助程序(如 <form method="post">)的详细信息,请参阅 ASP.NET Core 中的标记帮助程序

其他资源Additional resources

上一篇:添加模型下一步:数据库

作者:Rick Anderson

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

查看或下载示例。

“创建”、“删除”、“详细信息”和“编辑”页面The Create, Delete, Details, and Edit pages

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.AspNetCore.Mvc.RazorPages;
  7. using Microsoft.EntityFrameworkCore;
  8. using RazorPagesMovie.Models;
  9. namespace RazorPagesMovie.Pages.Movies
  10. {
  11. public class IndexModel : PageModel
  12. {
  13. private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
  14. public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
  15. {
  16. _context = context;
  17. }
  18. public IList<Movie> Movie { get;set; }
  19. public async Task OnGetAsync()
  20. {
  21. Movie = await _context.Movie.ToListAsync();
  22. }
  23. }
  24. }

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

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

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

  1. public async Task<IActionResult> OnPostAsync()
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return Page();
  6. }
  7. _context.Movie.Add(Movie);
  8. await _context.SaveChangesAsync();
  9. return RedirectToPage("./Index");
  10. }

检查 Pages/Movies/Index.cshtml Razor 页面 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <table class="table">
  11. <thead>
  12. <tr>
  13. <th>
  14. @Html.DisplayNameFor(model => model.Movie[0].Title)
  15. </th>
  16. <th>
  17. @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
  18. </th>
  19. <th>
  20. @Html.DisplayNameFor(model => model.Movie[0].Genre)
  21. </th>
  22. <th>
  23. @Html.DisplayNameFor(model => model.Movie[0].Price)
  24. </th>
  25. <th></th>
  26. </tr>
  27. </thead>
  28. <tbody>
  29. @foreach (var item in Model.Movie) {
  30. <tr>
  31. <td>
  32. @Html.DisplayFor(modelItem => item.Title)
  33. </td>
  34. <td>
  35. @Html.DisplayFor(modelItem => item.ReleaseDate)
  36. </td>
  37. <td>
  38. @Html.DisplayFor(modelItem => item.Genre)
  39. </td>
  40. <td>
  41. @Html.DisplayFor(modelItem => item.Price)
  42. </td>
  43. <td>
  44. <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
  45. <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
  46. <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
  47. </td>
  48. </tr>
  49. }
  50. </tbody>
  51. </table>

Razor 可以从 HTML 转换为 C# 或 Razor 特定标记。@ 符号后跟 Razor 保留关键字时,它会转换为 Razor 特定标记,否则会转换为 C#。

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

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

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

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

@model 指令The @model directive

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel

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

布局页The layout page

选择菜单链接(“RazorPagesMovie” 、“主页” 和“隐私” )。每页显示相同的菜单布局。菜单布局是在 Pages/Shared/_Layout.cshtml 文件中实现。打开 Pages/Shared/_Layout.cshtml 文件。

布局模板使你能够在一个位置指定网站的 HTML 容器布局,然后将它应用到网站中的多个页面。查找 @RenderBody() 行。RenderBody 是显示所创建的全部页面专用视图的占位符,已包装 在布局页中。例如,如果选择“隐私” 链接,Pages/Privacy.cshtml 视图在 RenderBody 方法中呈现。

ViewData 和布局ViewData and layout

考虑来自 Pages/Movies/Index.cshtml 文件中的以下代码:

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }

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

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

“Title”属性用于 Pages/Shared/_Layout.cshtml 文件 。以下标记显示 _Layout.cshtml 文件的前几行 。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>@ViewData["Title"] - RazorPagesMovie</title>
  7. @*Markup removed for brevity.*@

@Markup removed for brevity.@ 是不会出现在布局文件中的 Razor 注释。与 HTML 注释不同 (<!— —>),Razor 注释不会发送到客户端。

更新布局Update the layout

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

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>@ViewData["Title"] - Movie</title>

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

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

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

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

前面的定位点元素是一个标记帮助程序此处它是定位点标记帮助程序asp-page="/Movies/Index" 标记帮助程序属性和值可以创建指向 /Movies/Index Razor 页面的链接。asp-area 属性值为空,因此在链接中未使用区域。有关详细信息,请参阅区域

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

测试其他链接(“主页” 、“RpMovie” 、“创建” 、“编辑” 和“删除” )。每个页面都设置有标题,可以在浏览器选项卡中看到标题。将某个页面加入书签时,标题用于该书签。

备注

可能无法在 Price 字段中输入十进制逗号。若要使 jQuery 验证支持使用逗号(“,”)表示小数点的的非英语区域设置,以及支持非美国英语日期格式,必须执行使应用全球化的步骤。有关添加十进制逗号的说明,请参阅 GitHub 问题 4076

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

  1. @{
  2. Layout = "_Layout";
  3. }

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

“创建”页面模型The Create page model

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

  1. // Unused usings removed.
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.AspNetCore.Mvc.RazorPages;
  4. using RazorPagesMovie.Models;
  5. using System;
  6. using System.Threading.Tasks;
  7. namespace RazorPagesMovie.Pages.Movies
  8. {
  9. public class CreateModel : PageModel
  10. {
  11. private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
  12. public CreateModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
  13. {
  14. _context = context;
  15. }
  16. public IActionResult OnGet()
  17. {
  18. return Page();
  19. }
  20. [BindProperty]
  21. public Movie Movie { get; set; }
  22. public async Task<IActionResult> OnPostAsync()
  23. {
  24. if (!ModelState.IsValid)
  25. {
  26. return Page();
  27. }
  28. _context.Movie.Add(Movie);
  29. await _context.SaveChangesAsync();
  30. return RedirectToPage("./Index");
  31. }
  32. }
  33. }

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

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

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

  1. public async Task<IActionResult> OnPostAsync()
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return Page();
  6. }
  7. _context.Movie.Add(Movie);
  8. await _context.SaveChangesAsync();
  9. return RedirectToPage("./Index");
  10. }

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

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

创建 Razor 页面The Create Razor Page

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

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.CreateModel
  3. @{
  4. ViewData["Title"] = "Create";
  5. }
  6. <h1>Create</h1>
  7. <h4>Movie</h4>
  8. <hr />
  9. <div class="row">
  10. <div class="col-md-4">
  11. <form method="post">
  12. <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  13. <div class="form-group">
  14. <label asp-for="Movie.Title" class="control-label"></label>
  15. <input asp-for="Movie.Title" class="form-control" />
  16. <span asp-validation-for="Movie.Title" class="text-danger"></span>
  17. </div>
  18. <div class="form-group">
  19. <label asp-for="Movie.ReleaseDate" class="control-label"></label>
  20. <input asp-for="Movie.ReleaseDate" class="form-control" />
  21. <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
  22. </div>
  23. <div class="form-group">
  24. <label asp-for="Movie.Genre" class="control-label"></label>
  25. <input asp-for="Movie.Genre" class="form-control" />
  26. <span asp-validation-for="Movie.Genre" class="text-danger"></span>
  27. </div>
  28. <div class="form-group">
  29. <label asp-for="Movie.Price" class="control-label"></label>
  30. <input asp-for="Movie.Price" class="form-control" />
  31. <span asp-validation-for="Movie.Price" class="text-danger"></span>
  32. </div>
  33. <div class="form-group">
  34. <input type="submit" value="Create" class="btn btn-primary" />
  35. </div>
  36. </form>
  37. </div>
  38. </div>
  39. <div>
  40. <a asp-page="Index">Back to List</a>
  41. </div>
  42. @section Scripts {
  43. @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  44. }

Visual Studio 以用于标记帮助程序的特殊加粗字体显示 <form method="post"> 标记:

Create.cshtml 页的 VS17 视图

有关标记帮助程序(如 <form method="post">)的详细信息,请参阅 ASP.NET Core 中的标记帮助程序

Visual Studio for Mac 以用于标记帮助程序的特殊加粗字体显示 <form method="post"> 标记。

<form method="post"> 元素是一个表单标记帮助程序表单标记帮助程序会自动包含防伪令牌

基架引擎在模型中为每个字段(ID 除外)创建 Razor 标记,如下所示:

  1. <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  2. <div class="form-group">
  3. <label asp-for="Movie.Title" class="control-label"></label>
  4. <input asp-for="Movie.Title" class="form-control" />
  5. <span asp-validation-for="Movie.Title" class="text-danger"></span>
  6. </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 属性。

其他资源Additional resources

上一篇:添加模型下一步:数据库