学习ASP.NET Core Razor 编程系列八——并发处理
学习ASP.NET Core Razor 编程系列目录
学习ASP.NET Core Razor 编程系列二——添加一个实体
学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面
学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面
学习ASP.NET Core Razor 编程系列六——数据库初始化
学习ASP.NET Core Razor 编程系列七——修改列表页面
并发异常处理
在Visual Studio 2017的解决方案资源管理器中找到 Pages/Books/Edit.cshtml.cs 文件,鼠标双击打开 ,在代码中找到OnPostAsync方法。并按如下代码进行修改:
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _context.Attach(Book).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!_context.Book.Any(e => e.ID == Book.ID)) { return NotFound(); } else { throw; } } return RedirectToPage("./Index"); }
上面的代码功能是当检测到第一个客户端在删除书籍信息时,第二个客户端对要删除的书籍信息进行修改并保存时发生异常。
我们可以进行以下操作来重现上面的异常。
- 在 catch (DbUpdateConcurrencyException) 上设置断点。如下图。
2. 在Visual Studio 2017中按F5,运行应用程序,在打开的浏览器的一个窗口中,选择一本书籍进行修改。如下图。
3. 在另一个浏览器窗口中,选择同一本书籍信息的“Delete”链接,然后删除此书籍。
4. 在编辑书籍信息的浏览器窗口中,将书籍信息的修改内容保存到数据库。如下图。
5. 当两个或更多客户端同时更新记录时,代码通常将检测到并发冲突。如下图。
GET请求与POST请求
接下来我们根据 Pages/Books/Edit.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 Microsoft.EntityFrameworkCore; using RazorMvcBooks.Models; namespace RazorMvcBooks.Pages.Books { public class EditModel : PageModel { private readonly RazorMvcBooks.Models.BookContext _context; public EditModel(RazorMvcBooks.Models.BookContext context) { _context = context; } [BindProperty] public Book Book { get; set; } public async Task<IActionResult> OnGetAsync(int? id) { if (id == null) { return NotFound(); } Book = await _context.Book.SingleOrDefaultAsync(m => m.ID == id); if (Book == null) { return NotFound(); } return Page(); } public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _context.Attach(Book).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!_context.Book.Any(e => e.ID == Book.ID)) { return NotFound(); } else { throw; } } return RedirectToPage("./Index"); } } }
1. 当浏览器对Books/Edit 页面发出 HTTP GET 请求时(例如 http://localhost:5000/Books/Edit/9):
- OnGetAsync 方法从数据库提取书籍信息并把数据传递给Page 方法。
- Page 方法呈现“Pages/Books/Edit.cshtml”Razor 页面。 Pages/Books/Edit.cshtml 文件包含实体指令 (@model RazorMvcBooks.Pages.Books.EditModel),这使书籍实体在页面上可用。
- 页面中的表单会显示书籍实体中的值。
2. 当浏览器对Books/Edit 页面发出Post请求时:
- 此页面上的表单值将绑定到 Book 属性上。 [BindProperty] 特性会启用实体属性绑定。具体代码参见上面的代码。
- 如果实体对象的属性值中存在错误(例如,ReleaseDate 无法被转换为日期),则会使用已提交的值再次请求表单。
- 如果实体对象的属性值中没有错误,则把书籍信息保存到数据库。
“Index.cshtml”、“Create.cshtml”和“delete.cshtml”Razor 页面中的 HTTP GET 方法的实现原理与上面所述的Get请求类似。 “Create.cshtml”Razor 页面中的 POST请求方法的实现原理与上面所述的POST请求类似。
相关文章
- [Go] gocron源码阅读-go语言中数组和切片的字面值初始化语法
- [Linux] 纯净ubuntu快速搭建宝塔面板
- 解读顶会ICDE’21论文:利用DAEMON算法解决多维时序异常检测问题
- 云小课|VMware备份上云学习专列来了,快加入吧~
- ReScript 与 TypeScript,谁是前端圈的“当红辣子鸡”
- 50亿海量数据如何高效存储和分析? GaussDB (for Cassandra) 3个秘诀搞定
- 解读顶会CIKM'21 Historical Inertia论文
- 云小课|细数那些VMware虚拟机的恢复招式
- IoT边缘,你究竟是何方神圣?
- 深入分析3种线程池执行任务的逻辑方法
- 宝藏昇腾AI应用推荐!CANN带你体验黑白图像自动上色的快乐~
- 解读知识蒸馏模型TinyBert
- 鸿蒙轻内核的得力助手:带你掌握4种内存调试方法
- 从保证业务不中断,看网关的“前世今生”
- 为了让医院把医护还给患者,他们用了这个…
- 训练千亿参数模型的法宝,昇腾CANN异构计算架构来了~
- 数仓出现“wait in ccn queue”的时候,怎么迅速定位处理?
- 解析ThreadPoolExecutor类是如何保证线程池正确运行的
- 云小课|原来云备份不仅仅是能备份...
- 遇到联邦计算数据碰撞难题怎么办?不妨试一试PSI