建立基於ASP.NET core 3.1 的RazorPagesMovie項目(三)-已搭建基架的Razor頁面解釋和更新

 

本節主要介紹在上一節中經過搭建基架而建立的Razor頁面,並作一些UI改變。css

1、建立、刪除、詳細信息和編輯頁面

  一、雙擊Pages/Movies/Index.cshtml.cs文件,這是一個Razor頁面模型:

  

 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.Data;
 9 using RazorPagesMovie.Models;
10 
11 namespace RazorPagesMovie
12 {
13     public class IndexModel : PageModel
14     {
15         private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
16 
17         public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
18         {
19             _context = context;
20         }
21 
22         public IList<Movie> Movie { get;set; }
23 
24         public async Task OnGetAsync()
25         {
26             Movie = await _context.Movie.ToListAsync();
27         }
28     }
29 }

 

 

  ① 第13行:表示該Razor頁面派生自PageModel。約定:PageModel派生的類稱爲<PageName>Model。html

  ② 第17行:表示這是一個構造函數,使用依賴關係注入將RazorPagesMovieContent添加到頁。全部已搭建基架的頁面都遵循這個模式。jquery

  ③ 第24行:表示對頁面發出請求時,OnGetAsync方法向Razor頁面返回影片列表。調用OnGetAsync或OnGet以初始化頁面的狀態。OnGetAsync方法將得到的影片列表顯示出來。當OnGet返回void或OnGetAsync返回task時,使用任何返回語句。由於此時返回的Movie對象,在程序中作了定義(第22行)bootstrap

 二、雙擊Pages/Movies/Create.cshtml.cs文件,這也是一個Razor頁面模型:

 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.AspNetCore.Mvc.Rendering;
 8 using RazorPagesMovie.Data;
 9 using RazorPagesMovie.Models;
10 
11 namespace RazorPagesMovie
12 {
13     public class CreateModel : PageModel
14     {
15         private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
16 
17         public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
18         {
19             _context = context;
20         }
21 
22         public IActionResult OnGet()
23         {
24             return Page();
25         }
26 
27         [BindProperty]
28         public Movie Movie { get; set; }
29 
30         // To protect from overposting attacks, please enable the specific properties you want to bind to, for
31         // more details see https://aka.ms/RazorPagesCRUD.
32         public async Task<IActionResult> OnPostAsync()
33         {
34             if (!ModelState.IsValid)
35             {
36                 return Page();
37             }
38 
39             _context.Movie.Add(Movie);
40             await _context.SaveChangesAsync();
41 
42             return RedirectToPage("./Index");
43         }
44     }
45 }

 

  ④ 第3二、22行:當返回類型是IActionResult或Task<IActionResult>時,必須提供返回語句。瀏覽器

   三、雙擊Pages/Movies/Index.cshtml文件,這是一個Razor頁面:

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

 

 

  Razor能夠從HTML轉換爲C#或Razor特定的標記。當@符號後面跟着Razor保留關鍵字時,它會轉換爲Razor特定標記,不然會轉換爲C#。app

  ① 第1行:@page指令,它是一個Razor指令的一個示例。該指令表示將文件轉換爲一個MVC操做。這意味着它能夠處理請求。@page必須是頁面上第一個Razor指令。async

  ② 第17-26行:@Html 這是一系列的使用Lambda表達式的HTML幫助程序。DisplayNameFor HTML幫助程序檢查Lambda表達式引用的Tile、ReleaseDate等屬性來肯定顯示名稱。檢查Lambda表達式(而非求值),意味着model、model.Movie或model.Movie[0]爲null或空時,不會存在任何訪問衝突。函數

  ③ 第35-44行:@Html.DisplayFor是對Lambda表達式進行求值,將得到該模型的屬性值。佈局

  ④ 第2行:@model指令,指定傳遞給Razor頁面的模型類型。這個例子中的模型類型,就是第1段中派生於PageModel類的IndexModel模型。post

  ⑤ 第4-6行:@符號後面沒有Razor關鍵字,表示這是C#的一個示例。{}大括號中是C#代碼塊。這個頁面的引用的模型是IndexModel,它派生於PageModel,PageModel基類中包含ViewData字典屬性,可用於將數據傳遞到某個視圖。咱們能夠採用鍵值對的模式將對象添加到ViewData字典中。這裏,「Title」屬性被添加到ViewData字典中。而「Title」屬性又被用於/Pages/Shared/_Layout.cshtml文件中。見第4節中的第③條註釋。

   四、雙擊/Pages/Shared/_Layout.cshtml文件

 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"] - RazorPagesMovie</title>
 7     <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
 8     <link rel="stylesheet" href="~/css/site.css" />
 9 </head>
10 <body>
11     <header>
12         <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
13             <div class="container">
14                 <a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>
15                 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
16                         aria-expanded="false" aria-label="Toggle navigation">
17                     <span class="navbar-toggler-icon"></span>
18                 </button>
19                 <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
20                     <ul class="navbar-nav flex-grow-1">
21                         <li class="nav-item">
22                             <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
23                         </li>
24                         <li class="nav-item">
25                             <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
26                         </li>
27                     </ul>
28                 </div>
29             </div>
30         </nav>
31     </header>
32     <div class="container">
33         <main role="main" class="pb-3">
34             @RenderBody()
35         </main>
36     </div>
37 
38     <footer class="border-top footer text-muted">
39         <div class="container">
40             &copy; 2019 - RazorPagesMovie - <a asp-area="" asp-page="/Privacy">Privacy</a>
41         </div>
42     </footer>
43 
44     <script src="~/lib/jquery/dist/jquery.min.js"></script>
45     <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
46     <script src="~/js/site.js" asp-append-version="true"></script>
47 
48     @RenderSection("Scripts", required: false)
49 </body>
50 </html>

  ① 這是一個頁面佈局的模板(相似於母版頁)。它容許HTML容器具備以下佈局:在一個位置指定;應用於站點中的多個頁面。

  ② 第34行:@RenderBody(),是顯示所有頁面專用視圖的佔位符。

  ③ 第6行:經過@ViewData["Title"]將字典中的對象「Title」的值取出來,和字符串‘- RazorPagesMovie’一塊兒。最終造成頁面上咱們看到的標題:

  

 

 

   ④ Razor頁面的註釋方式採用:  @* 註釋內容*@  的方式進行註釋(區別於HTML的註釋<!-- 註釋-- >)。註釋不會被髮送到客戶端

 

 五、更新佈局

  ① 更改Title和連接頁面

    /Pages/Shared/_Layout.cshtml文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - 電影</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-page="/Movies/Index">個人電影</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

 

    這裏一共更改了2處:

    <title>@ViewData["Title"] - 電影</title>   

    <a class="navbar-brand" asp-page="/Movies/Index">個人電影</a>

    其中第二處更改,原先的代碼是:asp-area="" asp-page="/Movies/Index">,它表示一個標記幫助程序。更改以後,它是一個定位點標記幫助程序。asp-page="/Movies/Index"標記了幫助程序的屬性和值能夠建立指向/Movies/Index的Razor頁面的鏈接。其中,asp-area屬性值爲空,表示鏈接中未使用區域。

  Pages/Movies/Index.cshtml文件:

@page
@model RazorPagesMovie.IndexModel

@{
ViewData["Title"] = "首頁";
}

<h1>首頁</h1>

 

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

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

 

    這個標記,針對全部Razor文件將佈局文件設置爲Pages文件夾下的Pages/Shared/_Layout.cshtml。

  Pages/Movies/Create.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.AspNetCore.Mvc.Rendering;
 8 using RazorPagesMovie.Data;
 9 using RazorPagesMovie.Models;
10 
11 namespace RazorPagesMovie
12 {
13     public class CreateModel : PageModel
14     {
15         private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
16 
17         public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
18         {
19             _context = context;
20         }
21 
22         public IActionResult OnGet()
23         {
24             return Page();
25         }
26 
27         [BindProperty]
28         public Movie Movie { get; set; }
29 
30         // To protect from overposting attacks, please enable the specific properties you want to bind to, for
31         // more details see https://aka.ms/RazorPagesCRUD.
32         public async Task<IActionResult> OnPostAsync()
33         {
34             if (!ModelState.IsValid)
35             {
36                 return Page();
37             }
38 
39             _context.Movie.Add(Movie);
40             await _context.SaveChangesAsync();
41 
42             return RedirectToPage("./Index");
43         }
44     }
45 }

 

   第22行:OnGet方法初始化頁面所需的任何狀態。Create頁沒有任何要初始化的狀態,所以返回Page(),Page()方法建立用於呈現Create.cshtml頁的PageResult對象。後面,咱們會繼續學習OnGet初始化狀態的示例。

     第2七、28行:使用[BindProperty]特性,來給Movie屬性選擇加入模型綁定。當Create頁面發佈表單值(form 標記)時,ASP.NET Core運行時將發佈(post回傳)的值綁定到Movie模型。

     第32行:當頁面發佈(post)表單(form)數據時,將運行OnGetAsync方法。

     第34-37行:若是不存在任何模型錯誤,將從新顯示錶單,以及post回的任何表單數據。在post回form前,在能夠在客戶端捕獲到大部分的模型錯誤。模型錯誤的一個實例是:post回的日期字段值沒法轉換爲日期。

     第39-42行:若是不存在模型錯誤,將保存數據。最後瀏覽器會重定向到Index頁面。

  打開、更新Pages/Movies/Create.cshtml 的Razor頁面:

  

 1 @page
 2 @model RazorPagesMovie.CreateModel
 3 
 4 @{
 5     ViewData["Title"] = "添加";
 6 }
 7 
 8 <h1>新增</h1>
 9 
10 <h4>電影</h4>
11 <hr />
12 <div class="row">
13     <div class="col-md-4">
14         <form method="post">
15             <div asp-validation-summary="ModelOnly" class="text-danger"></div>
16             <div class="form-group">
17                 <label asp-for="Movie.Title" class="control-label">標題</label>
18                 <input asp-for="Movie.Title" class="form-control" />
19                 <span asp-validation-for="Movie.Title" class="text-danger"></span>
20             </div>
21             <div class="form-group">
22                 <label asp-for="Movie.ReleaseDate" class="control-label">發佈時間</label>
23                 <input asp-for="Movie.ReleaseDate" class="form-control" />
24                 <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
25             </div>
26             <div class="form-group">
27                 <label asp-for="Movie.Genre" class="control-label">題材</label>
28                 <input asp-for="Movie.Genre" class="form-control" />
29                 <span asp-validation-for="Movie.Genre" class="text-danger"></span>
30             </div>
31             <div class="form-group">
32                 <label asp-for="Movie.Price" class="control-label">價格</label>
33                 <input asp-for="Movie.Price" class="form-control" />
34                 <span asp-validation-for="Movie.Price" class="text-danger"></span>
35             </div>
36             <div class="form-group">
37                 <input type="submit" value="添加" class="btn btn-primary" />
38             </div>
39         </form>
40     </div>
41 </div>
42 
43 <div>
44     <a asp-page="Index">返回到電影列表</a>
45 </div>
46 
47 @section Scripts {
48     @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
49 }

 

 

    第14行:表示這個元素是一個表單標記幫助程序(form tag helper)。表單標記幫助程序會自動包含防僞令牌(antiforgery token)。

    第15-34行:基架引擎在模型中爲每一個字段(除ID外)建立Razor標記。

      其中<div asp-validation-summary>和<span asp-validation-for>一塊兒,用於顯示驗證錯誤。詳細的驗證信息之後再學習。

      <label asp-for="" class="">是標籤標記幫助程序(label tag helper)。生成一個標籤描述和Title屬性的for特性。(這裏咱們手動更改成「標題」)。

      <input asp_for="" class="">使用DataAnnotations屬性並在客戶端生成jQuery驗證所需的HTML屬性。

 六、驗證

  按下ctrl+F5,運行應用程序。測試咱們更改的效果。

相關文章
相關標籤/搜索