天天看點

學習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建立模闆頁面 學習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");
        }      

     上面的代碼功能是當檢測到第一個用戶端在删除書籍資訊時,第二個用戶端對要删除的書籍資訊進行修改并儲存時發生異常。

      我們可以進行以下操作來重制上面的異常。

  1. 在 catch (DbUpdateConcurrencyException) 上設定斷點。如下圖。
學習ASP.NET Core Razor 程式設計系列八——并發處理

         2. 在Visual Studio 2017中按F5,運作應用程式,在打開的浏覽器的一個視窗中,選擇一本書籍進行修改。如下圖。

學習ASP.NET Core Razor 程式設計系列八——并發處理

       3. 在另一個浏覽器視窗中,選擇同一本書籍資訊的“Delete”連結,然後删除此書籍。

學習ASP.NET Core Razor 程式設計系列八——并發處理

             4. 在編輯書籍資訊的浏覽器視窗中,将書籍資訊的修改内容儲存到資料庫。如下圖。

學習ASP.NET Core Razor 程式設計系列八——并發處理

          5. 當兩個或更多用戶端同時更新記錄時,代碼通常将檢測到并發沖突。如下圖。

學習ASP.NET Core Razor 程式設計系列八——并發處理

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請求類似。