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. 关于js无法设置input的value的问题

    html内容来自: <script type="text/html" id="theTemplate"> <input id="in ...

  2. poj 2546(两圆公共面积)

    Circular Area Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5682   Accepted: 2225 Des ...

  3. Android 显示或隐藏标题栏进度条TitleProgressBar

    1.新建项目,布局文件如下:activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/ ...

  4. Centos的APK解包打包签名

    http://www.v5b7.com/other/apk.html vi /etc/profile PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:/u ...

  5. 使用webView的时候,出现Error loading page Domain:WebKitErrorDomain Error Code:101 Description: The URL can't be shown

    onShouldStartLoadWithRequest = (e) => {// Implement any custom loading logic here, don't forget t ...

  6. (10)C#静态方法,静态字段,静态类,匿名类

    6.静态方法 使用静态方法就可不必用类的实例化调用次函数 class Test { public static void method() { ........ } //当调用一个method()时就 ...

  7. [COCI2015]ZGODAN

    题目大意: 给你一个数$n(n\leq10^1000)$,定义一个数是“美丽数”当且仅当这个数各个数位上的数奇偶性不同. 求最接近$n$的“美丽数”,若有多个,则依次输出. 思路: 贪心+高精度. 首 ...

  8. lua的table.sort

    local aa = {{a=11},{a=44},{a=33},{a=2} } table.sort(aa,function(a,b) return a.a>b.a end) for k, v ...

  9. 把我的漫画浏览器后台程序迁移到GAE上了

    这两天看了一下Python和GAE相关资料,作为练手,把我以前写的Windows 8下看漫画的程序的后台解析算法迁移到了GAE上了. 之前由于没有后台服务器,很多东西在本地实现起来不是很方便,现在拿G ...

  10. Winform 遍历 ListBox中的所有项

    foreach(DataRowView row in listBox.Items ) { MessageBox.Show(row["displayMember"].ToString ...