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

来源:https://www.cnblogs.com/hiwuchong/archive/2019/12/22/12081664.html
-Advertisement-
Play Games

本節主要介紹在上一節中通過搭建基架而創建的Razor頁面,並做一些UI改變。 一、創建、刪除、詳細信息和編輯頁面 1、雙擊Pages/Movies/Index.cshtml.cs文件,這是一個Razor頁面模型: ① 第13行:表示該Razor頁面派生自PageModel。約定:PageModel派 ...


 

本節主要介紹在上一節中通過搭建基架而創建的Razor頁面,並做一些UI改變。

一、創建、刪除、詳細信息和編輯頁面

  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。

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

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

 2、雙擊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 }

 

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

   3、雙擊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#。

  ① 第1行:@page指令,它是一個Razor指令的一個示例。該指令表示將文件轉換為一個MVC操作。這意味著它可以處理請求。@page必須是頁面上第一個Razor指令。

  ② 第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模型。

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

   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的註釋<!-- 註釋-- >)。註釋不會被髮送到客戶端

 

 5、更新佈局

  ① 更改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初始化狀態的示例。

     第27、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屬性。

 6、驗證

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • django內置的url轉換器,包括有int、str、uuid等等。但是有時候他們不能滿足我們的需求,因此就需要使用自定義url轉換器。自定義url轉換器的五步:1、定義一個類,直接繼承自object就可以2、在類中定義一個屬性regex,這個屬性是用來限制url轉換器規則的正則表達式。3、實現to ...
  • Date(基本已過時了,被Calendar替換) 構造方法(有兩個) Date(); Date(long l);long類型的毫秒值 常用方法(其他方法都已被Calendar替換) getTime()方法: 獲取時間的毫秒值 DateFormat(它是一個抽象類,用來將日期格式化) 一些常用的時間的 ...
  • //有一個使用cout<<GetName()的函數,每次執行結果都是只輸出了傳入字元串的首地址,即第一個字元,想了很久沒有找到辦法,後來將函數類型改為指針函數,結果就對了,仍然不是很明白為什麼可以這樣輸出,隱隱覺得函數的返回值仍然是一個地址,也許是cout函數的作用把後面的字元也輸出了,先記下來,之 ...
  • 當 Font 選擇的字體無法渲染時,則嘗試使用該選項所選擇的字體渲染。 ...
  • 時間原因直接上代碼,有空再解釋。 js代碼: //var tm=new Array(1) //tm[0]=e; ////tm[1]="%u5e72%u82e5%u4f5c%u5de5%u884c%u6267%u9662%u6cd5%u6c11%u4eba%u4e8e%u5173%u9662%u6cd ...
  • "5292. 劃分數組為連續數字的集合" 給你一個整數數組 和一個正整數 k,請你判斷是否可以把這個數組劃分成一些由 k 個連續數字組成的集合。 如果可以,請返回 True;否則,返回 False。 題目表述為集合,不是數組。 =__= 分析: 需要將數組按照k個一組劃分。所以一共有 個集合。如果不 ...
  • 瞭解來這麼久許可權控制許可權的知識,卻不知道如何寫代碼,網上的代碼多數並沒有多少完整的源碼能提供參考。偶然看到官網的例子,現在終於也把源碼的實現也弄得明白了一點。 tp5框架的Auth類可以實現頁面的訪問許可權,還可以精確到頁面上的按鈕。頁面訪問主要靠rule表的name欄位。附加條件許可權主要看condi ...
  • Indellij IDEA的菜單 File Edit View等主菜單欄不小心刪除,恢復的解決辦法 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...