Kerry 的筆記本
  • Table of contents
  • Kerry的Mac裝機必要
  • ASP.NET Core 教育訓練文件
    • .NET 9 OpenAPI 介紹與教學
    • 目錄
    • ASP.NET Core Authentication系列(一)理解Claim, ClaimsIdentity, ClaimsPrincipal
    • ASP.NET Core Authentication系列(三)Cookie選項
    • ASP.NET Core Authentication系列(二)實現認證、登錄和註銷
    • ASP.NET Core Authentication系列(四)基於Cookie實現多應用間單點登錄(SSO)
    • ASP.NET Core Consul 教學
    • ASP.NET Core Hangfire 排程管理
    • ASP.NET Core KeyCloak 實作
    • ASP.NET Core NLog-依照Environment使用Nlog.Config檔案
    • ASP.NET Core NLog-如何使用 NLog 將 log 寫到檔案
    • ASP.NET Core Nlog-發送訊息到ElasticSearch
    • 目錄
    • ASP.NET Core Quartz.NET 管理介面
    • ASP.NET Core RDLC 報表設計
    • ASP.NET Core SFTP (使用第三方套建 SSH.Net) - 類別庫為案例
    • ASP.NET Core 中使用 HttpReports 進行接口統計,分析, 可視化, 監控,追踪等
    • ASP.NET 使用 MassTransit 與 RabbitMQ,實現事件發佈、訂閱
    • Asp.Net Core 分散式Session – 使用 Redis
    • ASP.NET Core 前台會員修改個人資料
    • ASP.NET Core 前台會員忘記密碼與重設密碼
    • ASP.NET Core 前台會員登入
    • ASP.NET Core 前台會員註冊
    • ASP.NET Core 呼叫 API 發生 CORS 錯誤
    • ASP.NET Core 如何套網頁設計樣版
    • ASP.NET Core 客製化Model Validation 預設錯誤訊息
    • ASP.NET Core 後台查詢頁面教學
    • ASP.NET Core 網站生命週期
    • ASP.NET Feature Management 使用說明與教學
    • ASP.NET RulesEngine 介紹
    • ASP.NET WinForms APP 程式安裝檔
    • LinePay 支付完成後返回 LINE 應用而不跳出外部瀏覽器
    • EntityFramework
      • EF Core Migrations 完整教學手冊
      • EntityFramework Core DB Migrations
      • 使用 Entity Framework Core (EF Core) 的 Migrations 功能進行版本控制
    • NET 6
      • .NET 6 Autofac範例
      • .NET 6 Automapper範例
      • .NET 6 BenchmarkDotNet範例
      • .NET 6 Bogus範例
      • .NET 6 Dapper範例
      • .NET 6 Dapper語法說明
      • .NET 6 EFCore範例
      • .NET 6 EFCore語法說明
      • .NET 6 EPPlus圖表範例
      • .NET 6 EPPlus範例
      • .NET 6 Hangfire範例
      • .NET 6 HttpClient單元測試範例
      • .NET 6 MailKit前置作業
      • .NET 6 MailKit範例
      • .NET 6 Moq範例
      • .NET 6 NLog範例
      • .NET 6 NLog進階範例
      • .NET 6 Serilog範例
      • .NET 6 Serilog進階範例
      • .NET 6 Telegram.Bot前置作業
      • .NET 6 Telegram.Bot範例
      • .NET 6 Text.Json範例
      • .NET 6 swagger授權
      • .NET 6 swagger範例
      • .NET 6 xUnit範例
      • .NET 6 取得appsettings檔案內容
      • .NET 6 更改回傳Json時為大駝峰命名
      • .NET 6 解決System.Text.Json序列化後會將所有非ASCII轉為Unicode
    • WDMIS
      • CORS
      • FeatureManagement
      • Serilog
      • Spectre.Console
      • 資料模型實戰:從 MSSQL 設計到 .NET 8 WebAPI 實作(以刀具管理為例)
  • Azure
    • 如何在 ASP.NET CORE 5.0 WEB 應用程序中實現 AZURE AD 身份驗證
    • Azure App Configuration 使用教學
    • Azure Blob Storage
    • Azure DevOps 持續整合(CI) + Artifacts
  • CSharp
    • ASP.NET await 與 wait 的差異
    • AutoMapper —— 類別轉換超省力
    • C# 中的 HTTPClient — 入門指南
    • C# 正則表達式:從零到英雄指南
    • C# 集合, List<> 取交集、差集、聯集的方法
    • C#單元測試教學
    • CORS 介紹與設定方式
    • CSharp Coding Conventions
    • Using jQuery Unobtrusive AJAX in ASP.NET Core Razor Pages
    • 深入Dapper.NET源碼
    • 菜雞與物件導向
      • 菜雞與物件導向 (0): 前言
      • 菜雞與物件導向 (1): 類別、物件
      • 菜雞與物件導向 (10): 單一職責原則
      • 菜雞與物件導向 (11): 開放封閉原則
      • 菜雞與物件導向 (12): 里氏替換原則
      • 菜雞與物件導向 (13): 介面隔離原則
      • 菜雞與物件導向 (14): 依賴反轉原則
      • 菜雞與物件導向 (15): 最少知識原則
      • 菜雞與物件導向 (2): 建構式、多載
      • 菜雞與物件導向 (3): 封裝
      • 菜雞與物件導向 (4): 繼承
      • 菜雞與物件導向 (5): 多型
      • 菜雞與物件導向 (6): 抽象、覆寫
      • 菜雞與物件導向 (7): 介面
      • 菜雞與物件導向 (8): 內聚、耦合
      • 菜雞與物件導向 (9): SOLID
      • 菜雞與物件導向 (Ex1): 小結
  • DBeaver
    • 如何強制讓 DBeaver 在 Mac 上使用英文介面
  • DesignPattern
    • OAuth
    • Repository 模式 (Repository Pattern)
    • Single Sign On 實作方式介紹 (CAS)
    • 【SOP製作教學】新手適用,SOP範例、流程圖、製作流程全公開!
    • 【SOP製作教學】流程圖教學、重點範例、BPMN符號介紹!
    • 【SOP製作教學】流程圖符號整理、BPMN2.0進階符號教學!
    • 多奇數位 C# 程式碼撰寫規範 (C# Coding Guideline)
    • 軟體分層設計模式 (Software Layered Architecture Pattern)
    • 開源程式碼檢測平台 SonarQube
    • 菜雞新訓記
      • 菜雞新訓記 (0): 前言
      • 菜雞新訓記 (1): 使用 Git 來進行版本控制吧
      • 菜雞新訓記 (2): 認識 Api & 使用 .net Core 來建立簡單的 Web Api 服務吧
      • 菜雞新訓記 (3): 使用 Dapper 來連線到資料庫 CRUD 吧
      • 菜雞新訓記 (4): 使用 Swagger 來自動產生可互動的 API 文件吧
      • 菜雞新訓記 (5): 使用 三層式架構 來切分服務的關注點和職責吧
      • 菜雞新訓記 (6): 使用 依賴注入 (Dependency Injection) 來解除強耦合吧
      • 菜雞新訓記 (7): 使用 Fluent Validation 來驗證參數吧
  • DevOps
    • Repository 模式 (Repository Pattern)
    • pipeline工具研究
    • 單例模式 (Singleton Pattern)
    • 單元測試
    • 軟體分層設計模式 (Software Layered Architecture Pattern)
    • 雙重檢查鎖定模式 (Double-Checked Locking Pattern)
  • Docker
    • Docker 中部署 .NET 8 Web App 並支援 HTTPS
    • Docker指令大全
    • 第七章 安裝Nomad
    • Docker - 第三章 | 安裝 MSSQL
    • Docker - 第九章 | 安裝 datalust seq
    • 第二章 docker-compose 教學
    • Docker - 第五章 | 安裝 Redis
    • 第八章 安裝SonarQube
    • Docker - 第六章 | 安裝RabbitMQ
    • 第十一章 安裝 VtigerCRM
    • 第十二章 安裝KeyCloak
    • Docker - 第十章 | 安裝 Redmine
    • 第四章 安裝MySQL
    • Docker Desktop (含更改 Docker Image 路徑)
  • Git
    • Git Flow 指令大全(完整指令整理) 🚀
    • Git 安裝及配置SSH Key
    • Git 建立到上傳
    • 將現有專案的遠端儲存庫直接更改為新的儲存庫
    • Git 流程規劃
    • Git 語法大全
    • 30 天精通 Git 版本控管
      • 30 天精通 Git 版本控制
        • 第 01 天:认识 Git 版本控制
        • 第 02 天:在 Windows 平台必装的三套 Git 工具
        • 第 03 天:建立仓库
        • 第 04 天:常用的 Git 版本控制指令
        • 第 05 天:了解仓库、工作目录、物件与索引之间的关系
        • 第 06 天:解析 Git 资料结构 - 物件结构
        • 第 07 天:解析 Git 资料结构 - 索引结构
        • 第 08 天:关于分支的基本观念与使用方式
        • 第 09 天:比对文件与版本差异
        • 第 10 天:认识 Git 物件的绝对名称
        • 第 11 天:认识 Git 物件的一般参照与符号参照
        • 第 12 天:认识 Git 物件的相对名称
        • 第 13 天:暂存工作目录与索引的变更状态
        • 第 14 天: Git for Windows 选项设定
        • 第 15 天:标签 - 标记版本控制过程中的重要事件
        • 第 16 天:善用版本日志 git reflog 追踪变更轨迹
        • 第 17 天:关于合并的基本观念与使用方式
        • 第 18 天:修正 commit 过的版本历史记录 Part 1
        • 第 19 天:设定 .gitignore 忽略清单
        • 第 20 天:修正 commit 过的版本历史记录 Part 2
        • 第 21 天:修正 commit 过的版本历史记录 Part 3
        • 第 22 天:修正 commit 过的版本历史记录 Part 4 (Rebase)
        • 第 23 天:修正 commit 过的版本历史记录 Part 5
        • 第 24 天:使用 GitHub 远端仓库 - 入门篇
        • 第 25 天:使用 GitHub 远端仓库 - 观念篇
        • 第 26 天:多人在同一个远端仓库中进行版控
        • 第 27 天:通过分支在同一个远端仓库中进行版控
        • 第 28 天:了解 GitHub 的 fork 与 pull request 版控流程
        • 第 29 天:如何将 Subversion 项目汇入到 Git 仓库
        • 第 30 天:分享工作中几个好用的 Git 操作技巧
      • zh-tw
        • 第 01 天:認識 Git 版本控管
        • 第 02 天:在 Windows 平台必裝的三套 Git 工具
        • 第 03 天:建立儲存庫
        • 第 04 天:常用的 Git 版本控管指令
        • 第 05 天:了解儲存庫、工作目錄、物件與索引之間的關係
        • 第 06 天:解析 Git 資料結構 - 物件結構
        • 第 07 天:解析 Git 資料結構 - 索引結構
        • 第 08 天:關於分支的基本觀念與使用方式
        • 第 09 天:比對檔案與版本差異
        • 第 10 天:認識 Git 物件的絕對名稱
        • 第 11 天:認識 Git 物件的一般參照與符號參照
        • 第 12 天:認識 Git 物件的相對名稱
        • 第 13 天:暫存工作目錄與索引的變更狀態
        • 第 14 天: Git for Windows 選項設定
        • 第 15 天:標籤 - 標記版本控制過程中的重要事件
        • 第 16 天:善用版本日誌 git reflog 追蹤變更軌跡
        • 第 17 天:關於合併的基本觀念與使用方式
        • 第 18 天:修正 commit 過的版本歷史紀錄 Part 1
        • 第 19 天:設定 .gitignore 忽略清單
        • 第 20 天:修正 commit 過的版本歷史紀錄 Part 2
        • 第 21 天:修正 commit 過的版本歷史紀錄 Part 3
        • 第 22 天:修正 commit 過的版本歷史紀錄 Part 4 (Rebase)
        • 第 23 天:修正 commit 過的版本歷史紀錄 Part 5
        • 第 24 天:使用 GitHub 遠端儲存庫 - 入門篇
        • 第 25 天:使用 GitHub 遠端儲存庫 - 觀念篇
        • 第 26 天:多人在同一個遠端儲存庫中進行版控
        • 第 27 天:透過分支在同一個遠端儲存庫中進行版控
        • 第 28 天:了解 GitHub 的 fork 與 pull request 版控流程
        • 第 29 天:如何將 Subversion 專案匯入到 Git 儲存庫
        • 第 30 天:分享工作中幾個好用的 Git 操作技巧
  • Hands-On Labs - LineBotSDK 實作手札 (C#, .net core)
    • 00. 如何申請LINE Bot
    • CLI
      • 使用CLI來發送新的Channel Access Token(LINE Bot)
      • 使用CLI免費發送LINE Notify通知
    • basic
      • 如何發送LINE訊息(Push Message)
      • 如何發送LINE Template Messages
      • 如何發送ImageMap訊息
      • 如何發送Flex Message
      • 如何在訊息後面加上QuickReply快捷選項
    • liff
      • Lab 21: 建立第一個LIFF應用
    • webhook
      • 如何建立可Echo的基本LINE Bot
      • 如何在WebHook中取得用戶個人資訊(名稱、頭像、狀態)
      • 如何在WebHook中取得用戶上傳的圖片(Bytes)
  • Markdown
    • Markdown Cheatsheet 中文版
    • Markdown語法大全
    • 使用HackMD建立書本目錄
    • 使用HackMD建立簡報
  • SAP ABAP
    • ABAP開發環境和總體介紹
    • SAP MM模塊常用表總結
    • SAP QM數據庫表清單
    • SAP欄位與表的對應關係
  • SQL Server
    • [SQL SERVER] Like in
    • SQL Server 中,移除資料庫中所有的關聯限制
    • SQL Server 刪除資料庫中所有資料表
    • SQL Server View、Function 及 Stored Procedure 定義之快速備份
    • SSMS v18 清除登入畫面中,下拉選單歷史紀錄
    • [MS SQL]如何透過Database Mail進行郵件發送
    • [SQL SERVER]撰寫Stored Procedure小細節
    • 使用 Data Migration Assistant 移轉 SQL Server 資料庫與帳戶
    • 使用SSIS創建同步資料庫數據任務
  • Tools
    • 免費 FTP 伺服器 FileZilla Server 安裝教學 (新版設定)
  • VisualStudio
    • .NET CLI 指令碼介紹
    • Visual Studio 使用 Git 版本控制
    • 使用 Visual Studio 2022 可透過 .editorconfig 鎖定文字檔案的儲存編碼格式分享
  • Web API
    • ASP.NET Core 6 Web API 進行 JWT 令牌身份驗證
    • [ASP.NET Core]如何使用SwaggerAPI說明文件
    • ASP.NET Core Web Api實作JWT驗證筆記
    • ECFIT API 範例
    • JWT Token Authentication And Authorizations In .Net Core 6.0 Web API
    • 微服務架構 - 從狀態圖來驅動 API 的設計
  • Windows
    • [C#] 伺服器監控常用語法 (事件檢視器、CPU 硬碟使用率、程式執行狀況)
    • Configure IIS Web Server on Windows Server 2019
    • Log Paser Studio 分析 IIS W3C Log
    • Windows Server 2019 如何安裝 IIS 運行 ASP.NET 專案
    • 如何檢查安裝在 IIS 上的 .NET Core Hosting Bundle 版本
    • [IIS] 如何解決網站第一個請求 Request 特別慢 ?
    • IIS 不停機更版設置
    • SQL Server 2019 Standard 繁體中文標準版安裝
    • WINDOWS共用資料夾的網路認證密碼放在哪?如何清除?
    • 如何設定 ASP.NET CORE 網站應用程式持續執行在 IIS 上
  • 專案管理
    • SSDLC (Secure Software Development Life Cycle)
    • 系統開發原則
    • MIS及專案管理-使用Redmine
      • 第10章 - [日常管理]MIS部門週會工作進度追蹤
      • 第11章 - [日常管理]MIS部門主管月會報告管理
      • 第12章 - [日常管理]機房工作日誌
      • 第13章 - [日常管理]MIS部門耗用工時及工作進度檢討
      • 第14章 - [日常管理]MIS文件知識庫
      • 第15章 - [日常管理]整理及管理分享
      • 第16章 - [異常管理]使用者問題回報系統
      • 第17章 - [異常管理]資安事件及異常紀錄
      • 第18章 - [異常管理]整理及管理分享
      • 第19章 - [變革管理]MIS的專案及專案管理五大階段
      • 第1章 - [MIS及專案管理]中小企業MIS的鳥事
      • 第20章 - [變革管理]MIS的新專案管理:起始階段
      • 第21章 - [變革管理]MIS的新專案管理:規劃階段
      • 第22章 - [變革管理]MIS的新專案管理:執行階段
      • 第23章 - [變革管理]MIS的新專案管理:監控階段
      • 第24章 - [變革管理]MIS的新專案管理:結束階段
      • 第25章 - [變革管理]整理及管理分享
      • 第26章 - [ISMS管理]ISMS平台整體規劃
      • 第27章 - [ISMS管理]ISMS文管中心
      • 第28章 - [ISMS管理]ISMS表單紀錄的管理
      • 第29章 - [ISMS管理]整理及管理分享
      • 第2章 - [MIS及專案管理]專案管理的概念及MIS應用
      • 第30章 - 初心、來時路及感謝:系列文章總結回顧
      • 第3章 - [MIS及專案管理]管理工具的選擇
      • 第4章 - [Redmine]Redmine的安裝及設定
      • 第5章 - [Redmine]Redime系統邏輯說明
      • 第6章 - [Redmine]自行建立及維護表單
      • 第7章 - [Redmine]專案版面的規劃
      • 第8章 - [日常管理]AR管理
      • 第9章 - [日常管理]資訊服務申請
  • 微服務架構
    • DDD + CQRS + MediatR 專案架構
    • 微服務架構 #2, 按照架構,重構系統
    • 淺談微服務與網站架構的發展史
    • API First Workshop 設計概念與實做案例
      • API First #1 架構師觀點 - API First 的開發策略 - 觀念篇
      • API First #2 架構師觀點 - API First 的開發策略 - 設計實做篇
    • 基礎建設 - 建立微服務的執行環境
      • Part #1 微服務基礎建設 - Service Discovery
      • Part #2 微服務基礎建設 - 服務負載的控制
      • Part #3 微服務基礎建設 - 排隊機制設計
      • Part #4 可靠的微服務通訊 - Message Queue Based RPC
      • Part #5 非同步任務的處理機制 - Process Pool
    • 實做基礎技術 API & SDK Design
      • API & SDK Design #1, 資料分頁的處理方式
      • API & SDK Design #2, 設計專屬的 SDK
      • API & SDK Design #3, API 的向前相容機制
      • API & SDK Design #4, API 上線前的準備 - Swagger + Azure API Apps
      • API & SDK Design #5 如何強化微服務的安全性 API Token JWT 的應用
    • 建構微服務開發團隊
      • 架構面試題 #1, 線上交易的正確性
      • 架構面試題 #2, 連續資料的統計方式
      • 架構面試題 #3, RDBMS 處理樹狀結構的技巧
      • 架構面試題 #4 - 抽象化設計;折扣規則的設計機制
    • 架構師觀點 - 轉移到微服務架構的經驗分享
      • Part #1 改變架構的動機
      • Part #2 實際改變的架構案例
    • 案例實作 - IP 查詢服務的開發與設計
      • 容器化的微服務開發 #1 架構與開發範例
      • 容器化的微服務開發 #2 IIS or Self Host
  • 系統評估
    • RPA 與 WebAPI 評估
    • 數位轉型:從現有系統到數位化的未來
    • 數位轉型:從現有系統到數位化的未來
  • 面試
    • CV_黃子豪_2024
    • HR 問題集
    • .NET 工程師 面試問題集
    • 資深工程師 問題集
    • 資深開發人員 / 技術主管
    • 題目
Powered by GitBook
On this page
  • �إ߱M��
  • �]�p�d�߭���
  • ��Ʈw�y�k
  • �M�װ�¦�]�w
  • �d�ߤ��i
  • �W�[�����d�ߥ\��
  1. ASP.NET Core 教育訓練文件

ASP.NET Core 後台查詢頁面教學

PreviousASP.NET Core 客製化Model Validation 預設錯誤訊息NextASP.NET Core 網站生命週期

Last updated 1 year ago

�����}�o�`�����@�إ\��O�b��x�s�W���@��ơA�M��b�e�x��ܸ�ơA�����������i�γ̷s�����\��A�����оDZN�|�ЧA�p��إ߫�x���i���@�ɭ��A�æb�e�x��ܸ�ơC

���оǽd�ҷ|�إ� ASP.NET Core MVC �s�M�סA�s�W�@�ӫ�x���i�޲z�����A�z�L�d����ܸ�Ʈw�������i��ơC

�d�ߥ�����Ƨe�{�O²�檺�ʧ@�A�ӧڷ|�[�W�����d�߬۹�O���������ʧ@�A�ڷ|�ܽd�@�ӧڱ`�Ϊ�������k���U��ѦҡC

���d�Ҩϥ� ASP.NET Core MVC �����O .NET6�A�e�ݨϥ� Vue3 �ج[�A��ݸ�Ʈw�ϥ� SQL Server 2019�A�ϥ� Dapper �M��s�u�A�好���d�ҥi�H�U���C

�ؿ�

[2 �]�p�d�߭���](#step2) [4 �M�װ�¦�]�w](#step4) [4.1 � [4.2 � [4.3 ���� Json �^�ǹw�]�p�g�]�w](#step7) [5.1 View ��� [6 �W� [6.6 grid ����W�

�إ߱M��

�}�� Visual Studio 2022�A�إ߷s�M�׬��uASP.NET Core Web ���ε{�� (Model-View-Controller)�v�C

img1

��J�M�צW�١B���|�C

�[�c��ܡu.NET 6.0�v�����A���U�u�إߡv�N�|�إߦ��M�סC

�]�p�d�߭���

�o�̧ڭ̷s�W�@�� Controller �M���B�z��x�����i���@�C �b Controllers ���k��s�W�@�ӡu����v�C

��ܡuMVC ��� �V �ťաv, ���W���uAdmAnnoController�v�C

�b \Controllers\AdmAnnoController.cs �ɮת� Index() ���k���u�s�W�˵��v�A�i�H�s�W���� View �����C

��ܡuRazor �˵��v�A�W�ٺ����w�]�uIndex�v�A�Ŀ�u�ϥΪ����t�m���v�A���u�s�W�v�C

�ڳ]�p�F�d�ߵe���A�����ϥΥH�U�y�k���N \Views\AdmAnno\Index.cshtml �즳���y�k�C

<div id="QueryPanel" class="card">
    <div class="card-header">
        ���i���@
    </div>
    <div class="card-body">
        <div class="row">
            <div class="col-auto">
                <label for="AnnoSubject" class="col-form-label">���i�D�D</label>
            </div>
            <div class="col-auto">
                <input type="text" id="AnnoSubject" class="form-control">
            </div>
            <div class="col-auto">
                <label for="AnnoStatus" class="col-form-label">���i���A</label>
            </div>
            <div class="col-auto">
                <select class="form-select" id="AnnoStatus">
                    <option value="1">���</option>
                    <option value="0">����</option>
                </select>
            </div>
        </div>
    </div>
    <div class="card-header">
        <button type="button" class="btn btn-primary">�d��</button>
    </div>
	<div class="card-body">
		<table class="table">
			<thead>
				<tr>
					<th>���i���</th>
					<th>���i�D�D</th>
					<th>���i���e</th>
					<th>���i���A</th>
				</tr>
			</thead>
			<tbody>
			</tbody>
		</table>
	</div>
</div>

�NProgram.cs�ɮ׭˼ƲĤG�檺pattern: "{controller=Home}/{action=Index}/{id?}");�אּpattern: "{controller=AdmAnno}/{action=Index}/{id?}");�C

�� F5 ���������N�|�ݨ�H�U���e���C

����o�̥D�n�O���]�p�ڭ̪��e���A���U�ӴN�n�]�p��Ʈw�M��}�l�g�{���X�F�C

��Ʈw�y�k

�ڭ̷|�ϥ� SQL Server �ӷ��@��ƨӷ��A�ڤw�g�s�W�n ��Teach�� ����Ʈw�F�A���ۥH�U�y�k�s�W���i Table�C

CREATE TABLE [dbo].[Announcement] (
[Pkey] int IDENTITY(1, 1) NOT NULL,
[AnnoDate] date NOT NULL,
[AnnoSubject] nvarchar(50) NOT NULL,
[AnnoContent] nvarchar(1000) NOT NULL,
[AnnoStatus] smallint NOT NULL,
PRIMARY KEY CLUSTERED ([Pkey] ASC)
 ON [PRIMARY]
)

���F Table ����A�o�̧ڴN�����s�W 16 �����ո�ơA�]���ڭ̲Ĥ@�ӥ\��O�d�ߡA���F��Ƥ~��ݥX���G�C

insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-01 00:00:00',N'Subject1',N'Content1',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-02 00:00:00',N'Subject2',N'Content2',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-03 00:00:00',N'Subject3',N'Content3',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-04 00:00:00',N'Subject4',N'Content4',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-05 00:00:00',N'Subject5',N'Content5',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-06 00:00:00',N'Subject6',N'Content6',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-07 00:00:00',N'Subject7',N'Content7',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-08 00:00:00',N'Subject8',N'Content8',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-09 00:00:00',N'Subject9',N'Content9',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-10 00:00:00',N'Subject10',N'Content10',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-11 00:00:00',N'Subject11',N'Content11',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-12 00:00:00',N'Subject12',N'Content12',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-13 00:00:00',N'Subject13',N'Content13',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-14 00:00:00',N'Subject14',N'Content14',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-15 00:00:00',N'Subject15',N'Content15',1)
insert into [dbo].[Announcement]([AnnoDate],[AnnoSubject],[AnnoContent],[AnnoStatus]) values ('2022-02-16 00:00:00',N'Subject16',N'Content16',1)

�M�װ�¦�]�w

�o�̷|���w�� ASP.NET Core MVC �M�׼W�[�@�ǰ�¦�]�w�A�H��K����}�o�C

�[�J Vue3 �M��

Vue3 �O�e�ݱ�����쪺�ج[���O�w�A���} \Views\Shared_Layout.cshtml �ɮסA�b�U�� JavaScript �ޥμW�[ Vue3 ���O�w�y�k�A���Ǫ��n�D�n��b jQuery ����~��C

<script src="https://unpkg.com/vue@3"></script>

���b Layout �[�W Vue3 �ޥΫ�A�ڭ̴N�i�H�b�Ҧ��������ϥ� Vue3 �y�k�F�A���ޥλy�k�ӷ��i�Ѧҩx����C

�[�J jQuery BlockUI Plugin �M��

<script src="https://malsup.github.io/jquery.blockUI.js"></script>

���� Json �^�ǹw�]�p�g�]�w

�b .NET Framework �ϥ� Json �^�ǮɡA�e�ݦ��쪺 Json ����j�p�g�]�w�P ViewModel �ۦP�A�Ӧb .NET Core �ɫh�w�]�}�Y���p�g (�m�p���R�W)�A�o�̧ڳ��|�վ㦨�P ViewModel �ۦP�C

�b Program.cs �[�J�H�U�y�k�G

// ���� Json �^�Ǥj�p�g�P ViewModel �ۦP
builder.Services.AddControllers().AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

�d�ߤ��i

�o�̷|�}�l�g�{���X�A�b�]�p�e���W�� 2 �Ӭd�����A1 �Ӭd�߫��s�A�����U�d�߶s��A�a�J�d�߱���A�q��Ʈw��Ū����Ƨe�{�C

View ���[ Vue3 �y�k

���ڭ̦b Index.cshtml �ϥ� Bootstrap �]�p�n�F�e���A���ۭn�[�W Vue3 ���d�߰ʰ_�ӡC �N�H�U���y�k�����л\�� \Views\AdmAnno\Index.cshtml �̭��C

<div id="app">
    <div id="QueryPanel" class="card">
        <div class="card-header">
            ���i���@
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-auto">
                    <label for="queryFormAnnoSubject" class="col-form-label">���i�D�D</label>
                </div>
                <div class="col-auto">
                    <input type="text" id="queryFormAnnoSubject" class="form-control" v-model="queryForm.AnnoSubject">
                </div>
                <div class="col-auto">
                    <label for="queryFormAnnoStatus" class="col-form-label">���i���A</label>
                </div>
                <div class="col-auto">
                    <select class="form-select" id="queryFormAnnoStatus" v-model="queryForm.AnnoStatus">
                        <option value="1">���</option>
                        <option value="0">����</option>
                    </select>
                </div>
            </div>
        </div>
        <div class="card-header">
            <button type="button" class="btn btn-primary" v-on:click="Query()">�d��</button>
        </div>
		<div class="card-body">
			<table class="table">
				<thead>
					<tr>
						<th>���i���</th>
						<th>���i�D�D</th>
						<th>���i���e</th>
						<th>���i���A</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="(item, index) in grid.datas">
						<td>{{item.AnnoDate}}</td>
						<td>{{item.AnnoSubject}}</td>
						<td>{{item.AnnoContent}}</td>
						<td>{{item.AnnoStatusName}}</td>
					</tr>
				</tbody>
			</table>
		</div>
    </div>
</div>
@section scripts {
<script>
    const app = Vue.createApp({
    data() {
        return {
            queryForm:{
                AnnoSubject: ''
                , AnnoStatus: '1'
            }
            , grid:{
                datas:[]
            }
        }
    }
    , methods: {
        Query() {
            var self = this;
 
            // �զX������
            var postData = {};
            postData['AnnoSubject'] = self.queryForm.AnnoSubject;
            postData['AnnoStatus'] = self.queryForm.AnnoStatus;
			
            $.blockUI();
            // �ϥ� jQuery Ajax �ǰe�ܫ��
            $.ajax({
                url:'@Url.Content("~/AdmAnno/Query")',
                method:'POST',
                dataType:'json',
                data: { inModel: postData },
                success: function (datas) {
					$.unblockUI();
                    if (datas.ErrMsg) {
                        alert(datas.ErrMsg);
                        return;
                    }
                    // �j�w�C��
                    self.grid.datas = datas.Grid;
                },
                error: function (err) {
                    $.unblockUI();
                    alert(err.status + " " + err.statusText + '\n' + err.responseText);
                }
            });
 
        }
      }
    });
	const vm = app.mount('#app');
</script>
}

Controller �y�k

�b View �d�߫�|�I�s ~/AdmAnno/Query�A�b \Controllers\AdmAnnoController.cs �[�J�H�U Action�C

/// <summary>
/// �d�ߤ��i
/// </summary>
/// <param name="inModel"></param>
/// <returns></returns>
public IActionResult Query(QueryIn inModel)
{
	QueryOut outModel = new QueryOut();
	outModel.Grid = new List<AnnoModel>();
 
	// ��Ʈw�s�u�r��
	string connStr = _configuration.GetConnectionString("SqlServer");
	using (var cn = new SqlConnection(connStr))
	{
		// �D�n�d�� SQL
		string sql = @"SELECT Pkey, CONVERT(varchar(12) , AnnoDate, 111 ) as AnnoDate, AnnoSubject, AnnoContent, AnnoStatus, Case AnnoStatus when '1' then '���' when '0' then '����' end As AnnoStatusName
						FROM Announcement 
						WHERE 1=1 ";
 
		if (!string.IsNullOrEmpty(inModel.AnnoSubject))
		{
			sql += " AND AnnoSubject LIKE @AnnoSubject ";
		}
		if (!string.IsNullOrEmpty(inModel.AnnoStatus))
		{
			sql += " AND AnnoStatus = @AnnoStatus ";
		}
		sql += " ORDER BY AnnoDate desc, AnnoStatus ";
		
		object param = new
		{
			AnnoSubject = "%" + inModel.AnnoSubject + "%",
			AnnoStatus = inModel.AnnoStatus
		};
		
		// �ϥ� Dapper �d��
		var list = cn.Query<AnnoModel>(sql, param);
		
		// ��X����
		foreach (var item in list)
		{
			outModel.Grid.Add(item);
		}
	}
	return Json(outModel);
}

�� appsettings.json

�ڱN��Ʈw�s�u��b appsettings.json �̭��A���} appsettings.json ��A�[�J�H�U�s�u�r��C

"ConnectionStrings": {
	"SqlServer": "Data Source=127.0.0.1;Initial Catalog=Teach;Persist Security Info=false;User ID=test;Password=test;"
}

�b .NET 6 �n���o appsettings.json ���]�w�ӷ��A�n�b Controller �W�[�غc�lŪ�� Configuration�C

private readonly IConfiguration _configuration;
 
public AdmAnnoController(IConfiguration configuration)
{
	_configuration = configuration;
}

�w�� Dapper

�ڸ�Ʈw���ʪ���ϥηL�� ORM �M�� Dapper�A�ݭn�w�� Dapper �~��ϥΡC �}�ҡu�M�� > �޲z NuGet �M��v�C

�j�M�uDapper�v�A�w�˦��M��C

�إ� ViewModel

ViewModel �O�Ψөw�q Controller �P View ���������w�q�A�ڭ̭��إߤF�s Controller�A�ҥH�o���ӫإߥ������� ViewModel�C �b�uModel ���k�� > �[�J > ���O�v�C

�M��R�W�� ��AdmAnnoViewModel���C

�M��b AdmAnnoViewModel ���O�̭��A�[�J�b Controller �Ψ쪺 ViewModel�C

public class QueryIn
{
	public string AnnoSubject { get; set; }
	public string AnnoStatus { get; set; }
}
 
public class QueryOut
{
	public List<AnnoModel> Grid { get; set; }
}
 
public class AnnoModel
{
	public string Pkey { get; set; }
	public string AnnoDate { get; set; }
	public string AnnoSubject { get; set; }
	public string AnnoContent { get; set; }
	public string AnnoStatus { get; set; }
	public string AnnoStatusName { get; set; }
}

������o�̤���A�ڭ̴N�i�H����²�檺�d�ߥ\��F�A���U F5 ��A����u�d�ߡv�s�A�N�i�H��ܥX��Ʈw������ƤF�C

�i�O�o�ɭԧڭ��ٯʤ@�Ӥ������\��A���U�ӧڭ̴N�~�򧹦��������оǡC

�W�[�����d�ߥ\��

�����W�������˦��ܦh�ءA�ӧڴ��ѧڳ̱`�Ϊ� Vue3 �������󵹦U��ѦҡA�ڭ̫e�ݬO�إߦb Vue3 �W�����A�ҥH�ڷ|�b Vue3 �s�W�@�Ӥ���������C

�o�q���оǷ|��������@�I�A�ڬO�v�B�y�k�оǡA�p�G�L�k�z�Ѫ��ܡA�i��U���ݤ@�U���㪺�d�ҨӤ��|����e�����@�I�C

�s�W VuePagination.js ����

��������O�@�Ӧh�ƭ������|�Ψ쪺�\��A��ij�i�H�s�W�@���ɮסA�N�����޿�g�b�̭��A�M��b Vue3 �N����ޤJ�C

�b /js �ؿ����s�W�@���ɮסA�ɮשR�W�� ��VuePagination.js���C

�M��bVuePagination.js ���K�W�H�U�y�k�C

const VuePagination = {
    data() {
        return {
            PerPage:'�C��'
            , PageTiems:'��'
            , Page:'��'
            , Times:'��'
            , Total:'�@'
            , TotalPage:'��'
        }
    }
    , props: ['pagination']
    , template: `
        <div style="text-align:right">
            <span v-for="pageNo in pagination.pages">
                <a v-if="pagination.pageNo != pageNo" v-on:click="gotoPage(pageNo)" style="cursor:pointer">
                    {{ pageNo }}
                </a>
                <label v-else>
                    {{ "[" + pageNo + "]" }}
                </label>&nbsp;
            </span>
            <span class="pager-nav">
                �i{{PerPage}}&nbsp;<input type="text" maxlength="3" style="width:35px;text-align:center;font-size:12px;" name="pageSize" :value="pagination.pageSize" v-on:change="onchange"/>
                &nbsp;{{PageTiems}}�A
                {{Total}} {{pagination.totalPage}} {{TotalPage}} {{pagination.totalCount}} {{PageTiems}}�j
                <button type="button" class="btn btn-secondary btn-sm pager-btn" style="margin-bottom: 5px;margin-right:5px;" v-on:click="gotoPage()">Q</button>
            </span>
        </div>`
    , methods: {
        gotoPage(pageNo) {
            var self = this;
            console.log(pageNo);
            // �O�_���ǤJ���w����
            if (pageNo !== undefined) {
                if (pageNo === '<') {
                    self.pagination.pageNo = parseInt(self.pagination.pageNo) - 1;
                } else if (pageNo === '>') {
                    self.pagination.pageNo = parseInt(self.pagination.pageNo) + 1;
                } else if (pageNo === '<<') {
                    self.pagination.pageNo = (Math.floor((parseInt(self.pagination.pageNo) - 10) / 10) * 10 + 1);
                } else if (pageNo === '>>') {
                    self.pagination.pageNo = (Math.floor((parseInt(self.pagination.pageNo) + 10) / 10) * 10 + 1);
                } else {
                    self.pagination.pageNo = parseInt(pageNo);
                }
            } else {
                self.pagination.pageNo = 1;
            }
            // ���w���Ƭ�0�A�۰��ܧ�1
            if (parseInt(self.pagination.pageNo) === 0 || self.IsNumeric(self.pagination.pageNo) === false) {
                self.pagination.pageNo = 1;
            }
            // ���w���Ƥj���`���ơA�۰��ܧ��`����
            self.pagination.pageNo =
                parseInt(self.pagination.pageNo) > parseInt(self.pagination.totalPage)
                    ? self.pagination.totalPage : self.pagination.pageNo;
            // ���w���Ƭ�0�A�۰��ܧ�10
            if (parseInt(self.pagination.pageSize) === 0 || self.IsNumeric(self.pagination.pageSize) === false) {
                self.pagination.pageSize = 10;
            }
            // call on even
            this.$emit('requery', { pagination: self.pagination });
        }
        , onchange(e) {
            var self = this;
            var re = /[^0-9]/;
            if (re.test(e.target.value) === false) {
                self.pagination[e.target.name] = parseInt(e.target.value);
            }
        }
        , IsNumeric(n) {
            return (n - 0) === n && n.toString().length > 0;
        }
    }
};

�ޥ� VuePagination.js ����

�b \Views\Shared_Layout.cshtml �� JavaScript �W�[�ޥ� VuePagination.js �ɮסC

<script src="~/js/VuePagination.js"></script>

���U VuePagination.js ����

Vue3 ����ݭn���U�b\Views\AdmAnno\Index.cshtml�ɮת� Vue.createApp({}); ���~��A�� Vue ������U����A�W�٬� ��vue-pagination���C

app.component('vue-pagination', VuePagination);

�ϥΤ�������

���U�n����A�N�i�H�b�e���W��������m�A��W��������C

<vue-pagination v-bind:pagination="grid.pagination" v-on:requery="reQuery"></vue-pagination>

�]�������|���s�d�ߡA�ҥH�o����|�I�s�d�߭��� reQuery() �\��A���歫�s�d�ߡC

View �d�ߥ\��վ�

�ڭ̭��w�g�g�n�F�򥻪��d�� Query()�A�o�̦]�������\��A�վ�@�U�A�üW�[�@�� reQuery() �������ɥi�H���s�I�s�C �վ�᪺��k�O�G

Query(reQuery) {
	var self = this;
 
	if (reQuery !== 'reQuery') {
		self.grid.pagination.pageNo = 1;
	}
 
	// �զX������
	var postData = {};
	postData['AnnoSubject'] = self.queryForm.AnnoSubject;
	postData['AnnoStatus'] = self.queryForm.AnnoStatus;
 
	// ���[����
	postData['pagination'] =  JSON.parse(JSON.stringify(self.grid.pagination));
 
	$.blockUI();
	// �ϥ� jQuery Ajax �ǰe�ܫ��
	$.ajax({
		url:'@Url.Content("~/AdmAnno/Query")',
		method:'POST',
		dataType:'json',
		data: { inModel: postData },
		success: function (datas) {
			$.unblockUI();
			if (datas.ErrMsg) {
				alert(datas.ErrMsg);
				return;
			}
			// �j�w�C��
			self.grid.datas = datas.Grid;
			self.grid.pagination = datas.pagination;
		},
		error: function (err) {
			$.unblockUI();
			alert(err.status + " " + err.statusText + '\n' + err.responseText);
		}
	});
 
}
// ���歫�d
, reQuery(emitData) {
	var self = this;
	if (emitData !== undefined) {
		self.grid.pagination = emitData.pagination;
	}
	self.Query('reQuery');
}

grid ����W�[�����ݩ�

�b Vue3 �즳�ŧi�� data �ݩ� grid �n�W�[�@�Ӥ����ݩʡG

, pagination: {
	pages: [], pageNo: '1', pageSize: '10', totalCount: ''
}

Controller �d�ߥ\��վ�

�b Controller �쥻�]�g�n�F�򥻬d�ߥ\��A�o�̦]�W�[�����d�߫�A�]�n�վ�@�U�y�k�A�i�ΥH�U�y�k�������N�쥻���y�k�G

/// <summary>
/// �d�ߤ��i
/// </summary>
/// <param name="inModel"></param>
/// <returns></returns>
public IActionResult Query(QueryIn inModel)
{
	QueryOut outModel = new QueryOut();
	outModel.Grid = new List<AnnoModel>();
 
	// ��Ʈw�s�u�r��
	string connStr = _configuration.GetConnectionString("SqlServer");
	using (var cn = new SqlConnection(connStr))
	{
		// �D�n�d�� SQL
		string sql = @"SELECT Pkey, CONVERT(varchar(12) , AnnoDate, 111 ) as AnnoDate, AnnoSubject, AnnoContent, AnnoStatus, Case AnnoStatus when '1' then '���' when '0' then '����' end As AnnoStatusName
						FROM Announcement 
						WHERE 1=1 ";
 
		if (!string.IsNullOrEmpty(inModel.AnnoSubject))
		{
			sql += " AND AnnoSubject LIKE @AnnoSubject ";
		}
		if (!string.IsNullOrEmpty(inModel.AnnoStatus))
		{
			sql += " AND AnnoStatus = @AnnoStatus ";
		}
		sql += " ORDER BY AnnoDate desc, AnnoStatus ";
 
		object param = new
		{
			AnnoSubject = "%" + inModel.AnnoSubject + "%",
			AnnoStatus = inModel.AnnoStatus
		};
 
		// �����B�z
		int totalRowCount = 0;
		if (inModel.pagination.pageNo > 0)
		{
			string orderBy = "";
			// ���o�`����
			string totalRowSql = sql;
			if (totalRowSql.ToUpper().IndexOf("ORDER BY") > -1)
			{
				orderBy = totalRowSql.Substring(sql.ToUpper().LastIndexOf("ORDER BY"));
				totalRowSql = totalRowSql.Replace(orderBy, "");
			}
			totalRowSql = "SELECT COUNT(*) AS CNT FROM (" + totalRowSql + ") CNT_TABLE";
			var rowCnt = cn.Query(totalRowSql, param);
			foreach (var item in rowCnt)
			{
				totalRowCount = item.CNT;
			}
 
			// ���o���� SQL
			int startRow = ((inModel.pagination.pageNo - 1) * inModel.pagination.pageSize) + 1;
			int endRow = (startRow + inModel.pagination.pageSize) - 1;
			orderBy = sql.Substring(sql.ToString().ToUpper().LastIndexOf("ORDER BY"));
			sql = sql.Replace(orderBy, "");
			// �h�� Order by �O�W
			orderBy = orderBy.ToUpper().Replace("ORDER BY", "");
			StringBuilder newOrderBy = new StringBuilder();
			int index = 0;
			string[] orderBys = orderBy.Split(',');
			for (int i = 0; i < orderBys.Length; i++)
			{
				if (newOrderBy.Length > 0) { newOrderBy.Append(","); }
				string ob = orderBys[i];
				index = ob.IndexOf('.');
				if (index > -1)
				{
					newOrderBy.Append(ob.Substring(index + 1));
				}
				else
				{
					newOrderBy.Append(ob);
				}
			}
			newOrderBy.Insert(0, "ORDER BY ");
 
			sql = string.Concat(
				new object[] {
					"SELECT * FROM (SELECT *, ROW_NUMBER() OVER (", newOrderBy.ToString(), ") AS RCOUNT FROM (", sql, ") PAGE_SQL ) PAGE_SQL2 WHERE PAGE_SQL2.RCOUNT BETWEEN "
					, startRow, " AND ", endRow, " ", newOrderBy.ToString() });
		}
 
		// �ϥ� Dapper �d��
		var list = cn.Query<AnnoModel>(sql, param);
 
		// ��X����
		foreach (var item in list)
		{
			outModel.Grid.Add(item);
		}
 
		// �p�����
		outModel.pagination = this.PreparePage(inModel.pagination, totalRowCount);
	}
	return Json(outModel);
}
 
/// <summary>
/// �p�����
/// </summary>
/// <param name="model"></param>
/// <param name="TotalRowCount"></param>
/// <returns></returns>
public PaginationModel PreparePage(PaginationModel model, int TotalRowCount)
{
	List<string> pages = new List<string>();
	int pageStart = ((model.pageNo - 1) / 10) * 10;
	model.totalCount = TotalRowCount;
	model.totalPage =
			Convert.ToInt16(Math.Ceiling(
			 double.Parse(model.totalCount.ToString()) / double.Parse(model.pageSize.ToString())
			));
 
	if (model.pageNo > 10)
		pages.Add("<<");
	if (model.pageNo > 1)
		pages.Add("<");
	for (int i = 1; i <= 10; ++i)
	{
		if (pageStart + i > model.totalPage)
			break;
		pages.Add((pageStart + i).ToString());
	}
	if (model.pageNo < model.totalPage)
		pages.Add(">");
	if ((pageStart + 10) < model.totalPage)
		pages.Add(">>");
	model.pages = pages;
	return model;
}

�b SQL Server �������A�ڬO�����ק� SQL �y�k�A���d���`���ơA�A�d�߻ݭn���d���ơA���C�������ɡA���|���s�p��A�u�d�߻ݭn����ƽd��C

ViewModel �վ�

ViewModel �������N�O�W�[����������A�o�̧ڴN�����K�W�y�k�A�i�H�������N���e�� Model�C

public class QueryIn
{
	public string AnnoSubject { get; set; }
	public string AnnoStatus { get; set; }
 
	public PaginationModel pagination { get; set; }
}
 
public class QueryOut
{
	public List<AnnoModel> Grid { get; set; }
	public PaginationModel pagination { get; set; }
}
 
public class AnnoModel
{
	public string Pkey { get; set; }
	public string AnnoDate { get; set; }
	public string AnnoSubject { get; set; }
	public string AnnoContent { get; set; }
	public string AnnoStatus { get; set; }
	public string AnnoStatusName { get; set; }
}
 
/// <summary>
// ���� Model
/// </summary>
public class PaginationModel
{
	public List<string> pages { get; set; }
	public int pageNo { get; set; }
	public int pageSize { get; set; }
	public int totalPage { get; set; }
	public int totalCount { get; set; }
}

�������o�̫�A�N�i�H���դ������\��F�A�� F5 ����M�סA�d�߸�ƫ�N�|��ܤ��������G�C

������ 2 ���C

�o�O�ګܱ`�Ϊ��e�ݤ�������A���ɵ��A�C

img2
img3
img4
img5
img5-1

�e���]�p�ڭ̴N�q �ƻs�@�ǾA�X�d����ܪ��d�Ҩ� View �̭��C �ڥΨ쪺�˦��� , , ,

img6
img7

�O���e�ݦV��ݩI�s�ɡA�Ȯ���w�e�ݵe���A�H����G���I�������D�C �b���[�J Vue3 �M�󪺤U��A�[�J�ޥλy�k�C

img7-1
img8
img9
img10
img11
img12
img12-1
img13
img14
img15
img16
img20
img20-1
img17
img18
Bootstrap
Card
Form
Table
Button
jQuery BlockUI
1 �إ߱M��
3 ��Ʈw�y�k
�J Vue3 �M��
�J jQuery BlockUI Plugin �M��
5 �d�ߤ��i
Vue3 �y�k
5.2 Controller �y�k
5.3 �� appsettings.json
5.4 �w�� Dapper
5.5 �إ� ViewModel
�����d�ߥ\��
6.1 �s�W VuePagination.js ����
6.2 �ޥ� VuePagination.js ����
6.3 ���U VuePagination.js ����
6.4 �ϥΤ�������
6.5 View �d�ߥ\��վ�
�����ݩ�
6.7 Controller �d�ߥ\��վ�
6.8 ViewModel �վ�
6.9 �d�ҤU��