本节主要介绍在上一节中通过搭建基架而创建的Razor页面,并做一些UI改变。

一、创建、删除、详细信息和编辑页面

  1、双击Pages/Movies/Index.cshtml.cs文件,这是一个Razor页面模型:

  

 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.Data;
using RazorPagesMovie.Models; namespace RazorPagesMovie
{
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context; public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
} public IList<Movie> Movie { get;set; } public async Task OnGetAsync()
{
Movie = await _context.Movie.ToListAsync();
}
}
}

  ① 第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页面模型:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models; namespace RazorPagesMovie
{
public class CreateModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context; public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
} public IActionResult OnGet()
{
return Page();
} [BindProperty]
public Movie Movie { get; set; } // To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _context.Movie.Add(Movie);
await _context.SaveChangesAsync(); return RedirectToPage("./Index");
}
}
}

  ④ 第32、22行:当返回类型是IActionResult或Task<IActionResult>时,必须提供返回语句。

3、双击Pages/Movies/Index.cshtml文件,这是一个Razor页面:

 @page
@model RazorPagesMovie.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[].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[].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#。

  ① 第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文件

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorPagesMovie</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-area="" asp-page="/Index">RazorPagesMovie</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>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div> <footer class="border-top footer text-muted">
<div class="container">
&copy; - RazorPagesMovie - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer> <script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script> @RenderSection("Scripts", required: false)
</body>
</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属性:

 @{
Layout = "_Layout";
}

    这个标记,针对所有Razor文件将布局文件设置为Pages文件夹下的Pages/Shared/_Layout.cshtml。

  Pages/Movies/Create.cshtml.cs文件:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models; namespace RazorPagesMovie
{
public class CreateModel : PageModel
{
private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context; public CreateModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
{
_context = context;
} public IActionResult OnGet()
{
return Page();
} [BindProperty]
public Movie Movie { get; set; } // To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _context.Movie.Add(Movie);
await _context.SaveChangesAsync(); return RedirectToPage("./Index");
}
}
}

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

  

 @page
@model RazorPagesMovie.CreateModel @{
ViewData["Title"] = "添加";
} <h1>新增</h1> <h4>电影</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="添加" class="btn btn-primary" />
</div>
</form>
</div>
</div> <div>
<a asp-page="Index">返回到电影列表</a>
</div> @section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

    第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,运行应用程序。测试我们更改的效果。

创建基于ASP.NET core 3.1 的RazorPagesMovie项目(三)-已搭建基架的Razor页面解释和更新的更多相关文章

  1. 创建基于ASP.NET core 3.1 的RazorPagesMovie项目(二)-应用模型类配合基架生成工具生成Razor页面

    本节中,将学习添加用于管理跨平台的SQLLite数据库中的电影的类Movie.从ASP.NET core 模板创建的应用使用SQLLite数据库. 应用模型类(Movie)配合Entity Frame ...

  2. 创建基于ASP.NET core 3.1 的RazorPagesMovie项目(一)-创建和使用默认的模板

    声明:参考于asp.net core 3.1 官网(以后不再说明) 本教程是系列教程中的第一个教程,介绍生成 ASP.NET Core Razor Pages Web 应用的基础知识. 在本系列结束时 ...

  3. [译]基于ASP.NET Core 3.0的ABP v0.21已发布

    基于ASP.NET Core 3.0的ABP v0.21已发布 在微软发布仅仅一个小时后, 基于ASP.NET Core 3.0的ABP v0.21也紧跟着发布了. v0.21没有新功能.它只是升级到 ...

  4. 基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务

    本文首发于 码友网 -- <基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务> 前言 ...

  5. 基于ASP.NET Core 创建 Web API

    使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...

  6. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-1

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 本系列文章为翻译加上我个人的使用心得理解,希望帮助热爱学习的程序员. 珍重声明:本系列文章会跟原文有点出入,去掉了罗里吧嗦的文字. ...

  7. 如何基于asp.net core的Identity框架在mysql上作身份验证处理

    首先了解这个概念,我一开始也是理解和掌握基本的概念,再去做程序的开发.Identity框架是微软自己提供,基于.net core平台,可拓展.轻量 级.面向多个数据库的身份验证框架.IdentityS ...

  8. 基于ASP.Net Core开发的一套通用后台框架

    基于ASP.Net Core开发一套通用后台框架 写在前面 这是本人在学习的过程中搭建学习的框架,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 知其然,知其所以然,并非重 ...

  9. 基于ASP.NET Core 3.0快速搭建Razor Pages Web应用

    前言 虽然说学习新的开发框架是一项巨大的投资,但是作为一个开发人员,不断学习新的技术并快速上手是我们应该掌握的技能,甚至是一个.NET Framework开发人员,学习.NET Core 新框架可以更 ...

随机推荐

  1. tomcat 日志

    1.Tomcat的日志(./tomca/logs/) 分为5类,这里面 1和5比较重要 .catalina.--.log 或者 catalina.out: 引擎的日志文件 .host-manager. ...

  2. IO流之File对象

    File类: 用来将文件或者文件夹封装成对象 方便对文件与文件夹的属性等信息进行操作(因为流只能操作文件中的数据) File对象可以作为参考传递给流的构造函数 上下级文件夹之间使用分隔符分开: 在Wi ...

  3. C# MemoryCache学习笔记

    很多情况下需要用到缓存,合理利用缓存一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.为了避免每次请求都去访问后台的 资源(例如数据库),一般会考虑将一些更新不是很频繁的.可以重用的数据 ...

  4. redis之master.slave主从复制

    简介 主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,master以写为主,slave以读为主 从库配置 配置从库,不配主库 配置从库: 格式: slaveof 主库ip ...

  5. Windows应急响应和系统加固(2)——Windows应急响应的命令使用和安全检查分析

    Windows应急响应的命令使用和安全检查分析 1.获取IP地址: ·ipconfig /all,获取Windows主机IP地址信息: ·ipconfig /release,释放网络IP位置: ·ip ...

  6. Mac-MacOS降级(Mac系统降级,系统回退)

    前言 最近把macOS更新到了 macOS Catalina,使用了一段时间后,结合自己的使用环境和体验,感觉 Catalina 不太好用,就想把系统回退到 macOS Mojave,但是平时几乎不用 ...

  7. dmock 基于Django的轻量级Mock平台

    GitHub:https://github.com/yjlch1016/dmock # dmock 基于Django的轻量级Mock平台 dmock即Django+Mock的缩写 一.思路: mock ...

  8. unity 教程Tanks中的Transform.InverseTransformPoint理解

    Tanks教程中在处理摄像机缩放的时候使用了下面的函数,取两个坦克的中心点之后,根据两个坦克之间的距离,保证两个坦克都在屏幕中,然后进行缩放. private float FindRequiredSi ...

  9. Python——面向对象,简易学生信息管理系统

    一.概述 1.1涉及到的知识点 项目开发:创建项目,创建包,导入包: 面向对象:静态方法,继承,内置函数,自定义函数: 数据类型:列表,字典,字符串.列表.字典的转换和自动生成导向: 异常处理:捕获异 ...

  10. 【小白视频学Java for循环】3分钟学会Java的for循环,让看懂for循环嵌套再不是难事

    目录 一.单个for循环介绍 二.for循环嵌套 听讲时能听懂的for循环为什么一做题就晕菜?一个for循环还勉强能看懂,但为什么一看到双重for循环脑子里就感觉脑子全是浆糊? 如果有上述问题那么就继 ...