https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/da1

我们的电影应用有个不错的开始,但是展示效果还不够理想。 我们不希望看到时间(如下图所示的 12:00:00 AM),并且“ReleaseDate”应为“Release Date”(两个词)。

修改代码

打开 Models/Movie.cs 文件,并添加以下代码中突出显示的行:

using System;
using System.ComponentModel.DataAnnotations;//引入命名空间
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; } [Display(Name = "更新日期")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}

我们将在下一教程中介绍 DataAnnotations。

Display 特性指定要显示的字段名称的内容(本例中应为“更新日期”,而不是“ReleaseDate”)。

DataType 属性指定数据的类型(日期),使字段中存储的时间信息不会显示。

运行效果如图

同理可修改标题等字段表头。

浏览到 Pages/Movies,并将鼠标悬停在“编辑”链接上以查看目标 URL。

“编辑”、“详细信息”和“删除”链接是在 Pages/Movies/Index.cshtml 文件中由定位标记帮助程序生成的。

@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 元素。 在前面的代码中,AnchorTagHelper 从 Razor 页面(路由是相对的)、asp-page 和路由 ID (asp-route-id) 动态生成 HTML href 特性值。 有关详细信息,请参阅页面的 URL 生成

在最喜欢的浏览器中使用“查看源代码”来检查生成的标记。 生成的 HTML 的一部分如下所示:

<td>
<a href="/Movies/Edit?id=1">Edit</a> |
<a href="/Movies/Details?id=1">Details</a> |
<a href="/Movies/Delete?id=1">Delete</a>
</td>

动态生成的链接通过查询字符串传递电影 ID(例如 http://localhost:5000/Movies/Details?id=2)。

更新“编辑”、“详细信息”和“删除”Razor 页面以使用“{id:int?}”路由模板。 将上述每个页面的页面指令从 @page 更改为 @page "{id:int}"

运行应用,然后查看源代码。 生成的 HTML 会将 ID 添加到 URL 的路径部分:

<td>
<a href="/Movies/Edit/1">Edit</a> |
<a href="/Movies/Details/1">Details</a> |
<a href="/Movies/Delete/1">Delete</a>
</td>

如果对具有“{id: int}” 路由模板的页面进行的请求中不包含整数,则将返回 HTTP 404(未找到)错误。 例如,http://localhost:5000/Movies/Details 将返回 404 错误。 若要使 ID 可选,请将 ? 追加到路由约束:

@page "{id:int?}"//多一个问号,表示参数可选

更新并发异常处理

在 Pages/Movies/Edit.cshtml.cs 文件中更新 OnPostAsync 方法。 下列突出显示的代码显示了更改:

public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _context.Attach(Movie).State = EntityState.Modified; try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!_context.Movie.Any(e => e.ID == Movie.ID))
{
return NotFound();
}
else
{
throw;
}
} return RedirectToPage("./Index");
}

之前的代码仅检测当第一个并发客户端删除电影以及第二个并发客户端对电影发布更改时的并发异常。

测试 catch 块:

  • 在 catch (DbUpdateConcurrencyException) 上设置断点
  • 编辑电影。
  • 在其他浏览器窗口中,选择同一电影的“删除”链接,然后删除此电影。
  • 在之前的浏览器窗口中,将更改发布到电影。

当两个或更多客户端同时更新记录时,生产代码通常将检测到并发冲突。 有关详细信息,请参阅处理并发冲突

发布和绑定审阅

检查 Pages/Movies/Edit.cshtml.cs 文件:

public class EditModel : PageModel
{
private readonly RazorPagesMovie.Models.MovieContext _context; public EditModel(RazorPagesMovie.Models.MovieContext context)
{
_context = context;
} [BindProperty]
public Movie Movie { get; set; } public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
} Movie = await _context.Movie.SingleOrDefaultAsync(m => m.ID == id); if (Movie == null)
{
return NotFound();
}
return Page();
} public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} _context.Attach(Movie).State = EntityState.Modified; try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!_context.Movie.Any(e => e.ID == Movie.ID))
{
return NotFound();
}
else
{
throw;
}
} return RedirectToPage("./Index");
}
}

当对 Movies/Edit 页面进行 HTTP GET 请求时(例如 http://localhost:5000/Movies/Edit/2):

  • OnGetAsync 方法从数据库提取电影并返回 Page 方法。
  • Page 方法呈现“Pages/Movies/Edit.cshtml”Razor 页面。 Pages/Movies/Edit.cshtml 文件包含模型指令 (@model RazorPagesMovie.Pages.Movies.EditModel),这使电影模型在页面上可用。
  • “编辑”表单中会显示电影的值。

当发布 Movies/Edit 页面时:

  • 此页面上的表单值将绑定到 Movie 属性。 [BindProperty] 特性会启用模型绑定

[BindProperty]
public Movie Movie { get; set; }
  • 如果模型状态中存在错误(例如,ReleaseDate 无法被转换为日期),则会使用已提交的值再次发布表单。

  • 如果没有模型错误,则电影已保存。

“索引”、“创建”和“删除”Razor 页面中的 HTTP GET 方法遵循一个类似的模式。 “创建”Razor 页面中的 HTTP POST OnPostAsync 方法遵循的模式类似于“编辑”Razor 页面中的 OnPostAsync 方法所遵循的模式。

在下一教程中将添加搜索。

ASP.NET CORE RAZOR :个性化显示的更多相关文章

  1. 学习ASP.NET Core Razor 编程系列一

    一. 概述 .NET Core 1.0发布的时候就想进行学习的,不过根据微软的以往的发布规律1.0版可以认为是大众测试版,2.0才算稳定.现在2.1都已经发布了预览版,之前对其"不稳定&qu ...

  2. 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  3. 学习ASP.NET Core Razor 编程系列七——修改列表页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  4. 学习ASP.NET Core Razor 编程系列八——并发处理

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. 学习ASP.NET Core Razor 编程系列九——增加查询功能

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  6. ASP.Net Core Razor+AdminLTE 小试牛刀

    AdminLTE 一个基于 bootstrap 的轻量级后台模板,这个前端界面个人感觉很清爽,对于一个大后端的我来说,可以减少较多的时间去承担前端的工作但又必须去独立去完成一个后台系统开发的任务,并且 ...

  7. 学习ASP.NET Core Razor 编程系列十九——分页

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. 学习ASP.NET Core Razor 编程系列十七——分组

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  10. 学习ASP.NET Core Razor 编程系列十六——排序

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

随机推荐

  1. 解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.17' not found问题

    在项目中使用第三方动态库时,出现异常:/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.17' not found 查看系统库时,发现确实没有对应的版本: ...

  2. 解决iOS10的Safari下Meta设置user-scalable=no无效的方法

    苹果为了提高Safari中网站的辅助功能,屏蔽了Meta下的user-scalable=no功能.所以在iOS10下面,就算加上user-scalable=no,Safari浏览器也能支持手动缩放. ...

  3. [thinkphp] 如何解析ajaxReturn返回的json字符串

    success: function(data){ var dataObj=eval("("+data+")");//转换为json对象 alert(dataOb ...

  4. HDU 6235.Permutation (2017中国大学生程序设计竞赛-哈尔滨站-重现赛)

    Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  5. (2)新概念英语一(1-10)lessons

    一共105个单词 lesson1 lesson2 lesson3 lesson4 lesson5 lesson6 lesson7 lesson8 lesson9 lesson10

  6. Python的程序结构[1] -> 方法/Method[0] -> 类实例方法、私有方法和抽象方法

    类实例方法.私有方法和抽象方法 Python中最常用的就是类实例方法,类似于属性中的类实例属性,同时,也存在与私有属性类似方法,即私有方法,下面介绍这两种常见的方法,以及一种特殊意义的类实例方法 -- ...

  7. 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  8. [POI2014]Criminals

    题目大意: 给你一个长度为$n(n\le10^6)$的颜色序列,其中每个颜色互不相同.两个人$A$和$B$分别从某个点出发从左往右.从右往左任意地选择颜色,然后在中间的某一点相遇.分别给出两人所选择的 ...

  9. [POI2014]Ant colony

    题目大意: 给定一棵$n(n\le10^6)$个结点的树.在每个叶子结点,有$g$群蚂蚁要从外面进来,其中第$i$群有$m_i$只蚂蚁.这些蚂蚁依次爬树(一群蚂蚁爬完后才会爬另一群),若当前经过结点度 ...

  10. log4j配置文件中的additivity属性

    它是 子Logger 是否继承 父Logger 的 输出源(appender)的标志位.具体说,默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger ...