隨著技術的進步,跨平臺開發已經成為了標配,在此大背景下,ASP.NET Core也應運而生。本文主要基於ASP.NET Core+Element+Sql Server開發一個校園圖書管理系統為例,簡述基於MVC三層架構開發的常見知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
隨著技術的進步,跨平臺開發已經成為了標配,在此大背景下,ASP.NET Core也應運而生。本文主要基於ASP.NET Core+Element+Sql Server開發一個校園圖書管理系統為例,簡述基於MVC三層架構開發的常見知識點,僅供學習分享使用,如有不足之處,還請指正。
涉及知識點
在本示例中,涉及到B/S全棧開發的常見知識點,包括後端與前端,主要如下:
- 開發工具:Visual Studio 2022
- 目標框架:.Net 6.0
- 架構:MVC三層架構【Model-View-Controller】
- 前端框架:前端採用Element框架,一套為開發者、設計師和產品經理準備的基於 Vue 2.0 的桌面端組件庫。可以大大提高開發效率,減少工作量。
- 資料庫:SQL Server 2012。需要掌握基礎的增刪改查語句使用。
Element框架簡介
Element,一套為開發者、設計師和產品經理準備的基於 Vue 2.0 的桌面端組件庫。具體組件使用方法,可參考官網:https://element.eleme.io/#/zh-CN,
搭建開發框架
工欲善其事必先利其器,所以開發具體功能之前,首先要搭建開發環境,步驟如下所示:
1. 創建項目
本示例中的校園圖書管理系統,基於ASP.NET Core MVC三層架構,在創建時選擇對應模板即可,如下所示:
根據創建嚮導進行創建即可,在項目名稱處輸入CLMS,目標框架選擇.Net6.0即可。為了項目可移植性,將DAL層和Entity層獨立出來成單獨的工程。項目結構如下所示:
2. 創建資料庫
在本示例中,採用Data First方式,先創建資料庫和對應的表結構,根據業務需求分析,
主要包括三部分:
- 書室管理:書室信息(Librarys),書架信息(BookRacks)
- 圖書管理:書籍信息(Book),借還記錄(Circulates)
- 系統管理:用戶信息(Users),角色信息(Roles),菜單信息(Menus)以及角色許可權分配(RoleMenus),用戶角色分配(RoleMenus)
如下所示:
3. 在項目中配置資料庫
連接資料庫,需要在配置文件appsettings.json中,添加資料庫連接字元串,如下所示:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "ConnectionStrings": { "Default": "Server=localhost;Database=CLMS;Trusted_Connection=True;User Id=sa;Password=abc123;Encrypt=True;TrustServerCertificate=True;" }, "AllowedHosts": "*" }
4. 創建資料庫操作對象上下文
EntityFrameWork框架需要進行安裝,目前版本為7.0.1,可通過NuGet包管理器進行安裝,如下所示:
資料庫操作採用EntityFrameCore框架,繼承自DbContext,如下所示:
1 using CLMS.Entity; 2 using Microsoft.EntityFrameworkCore; 3 4 namespace CLMS.DAL 5 { 6 /// <summary> 7 /// 創建資料庫上下文類 8 /// </summary> 9 public class DataContext : DbContext 10 { 11 public DbSet<UserEntity> Users { get; set; } 12 13 public DbSet<MenuEntity> Menus { get; set; } 14 15 public DbSet<RoleEntity> Roles { get; set; } 16 17 public DbSet<UserRoleEntity> UserRoles { get; set; } 18 19 public DbSet<RoleMenuEntity> RoleMenus { get; set; } 20 21 /// <summary> 22 /// 圖書室 23 /// </summary> 24 public DbSet<LibraryEntity> Librarys { get; set; } 25 26 /// <summary> 27 /// 閱覽架 28 /// </summary> 29 public DbSet<BookRackEntity> BookRacks { get; set; } 30 31 /// <summary> 32 /// 借還記錄 33 /// </summary> 34 public DbSet<CirculateEntity> Circulates { get; set; } 35 36 /// <summary> 37 /// 圖書 38 /// </summary> 39 public DbSet<BookEntity> Books { get; set; } 40 41 public DataContext(DbContextOptions options) : base(options) 42 { 43 44 } 45 46 protected override void OnModelCreating(ModelBuilder modelBuilder) 47 { 48 base.OnModelCreating(modelBuilder); 49 modelBuilder.Entity<UserEntity>().ToTable("Users"); 50 modelBuilder.Entity<MenuEntity>().ToTable("Menus"); 51 modelBuilder.Entity<RoleEntity>().ToTable("Roles"); 52 modelBuilder.Entity<UserRoleEntity>().ToTable("UserRoles"); 53 modelBuilder.Entity<RoleMenuEntity>().ToTable("RoleMenus"); 54 // 55 modelBuilder.Entity<LibraryEntity>().ToTable("Librarys"); 56 modelBuilder.Entity<BookRackEntity>().ToTable("BookRacks"); 57 modelBuilder.Entity<CirculateEntity>().ToTable("Circulates"); 58 modelBuilder.Entity<BookEntity>().ToTable("Books"); 59 } 60 } 61 }
5. EntityFramework配置
在Startup.cs中,添加EntittyFramework的註入,如下所示:
1 using Autofac.Extensions.DependencyInjection; 2 using CLMS.DAL; 3 using Microsoft.EntityFrameworkCore; 4 5 var builder = WebApplication.CreateBuilder(args); 6 7 // Add services to the container. 8 builder.Services.AddControllersWithViews(); 9 builder.Services.AddDbContext<DataContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); 10 builder.Services.AddHttpContextAccessor(); 11 builder.Services.AddSession();//配置session訪問服務 12 // 以下是autofac依賴註入 13 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); 14 var app = builder.Build(); 15 16 // Configure the HTTP request pipeline. 17 if (!app.Environment.IsDevelopment()) 18 { 19 app.UseExceptionHandler("/Home/Error"); 20 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 21 app.UseHsts(); 22 } 23 24 app.UseHttpsRedirection(); 25 26 app.UseStaticFiles(); 27 28 app.UseRouting(); 29 app.UseSession(); 30 app.UseAuthorization(); 31 32 app.MapControllerRoute( 33 name: "default", 34 pattern: "{controller=Home}/{action=Index}/{id?}"); 35 36 app.Run();
6. 安裝客戶端框架
在本示例中,主要用到Element UI框架,以及axios框,Vue2.0,可通過Visual Studio進行安裝,如下所示:
選擇Web項目,右鍵-->添加-->客戶端庫。打開添加視窗,然後選擇對應庫進行安裝即可,如下所示:
安裝成功後,如下所示:
登錄頁面
當基礎開發環境搭建好後,就可以進行具體功能開發,以登錄功能為例,步驟如下:
1. 創建控制器LoginController
控制器主要負責頁面導航和邏輯處理,如下所示:
1 namespace CLMS.Host.Controllers 2 { 3 public class LoginController : Controller 4 { 5 private DataContext dataContext; 6 7 public LoginController(DataContext context) 8 { 9 dataContext = context; 10 } 11 12 [HttpGet] 13 public IActionResult Index() 14 { 15 return View(); 16 } 17 18 [Consumes("application/json")] 19 [HttpPost] 20 public Msg Login([FromBody]User user) 21 { 22 Msg msg = new Msg(); 23 if (string.IsNullOrEmpty(user.UserName) || string.IsNullOrEmpty(user.Password)) 24 { 25 msg.message = "用戶名或密碼為空"; 26 msg.code = 1; 27 return msg; 28 } 29 else 30 { 31 var item = dataContext.Users.FirstOrDefault(i => i.UserName == user.UserName && i.Password == user.Password); 32 if (item != null) 33 { 34 HttpContext.Session.SetInt32("UserId", item.Id); 35 msg.message = "success"; 36 msg.code = 0; 37 return msg; 38 } 39 else 40 { 41 msg.message = "用戶名或密碼驗證錯誤"; 42 msg.code = 1; 43 return msg; 44 } 45 46 } 47 } 48 } 49 }
2. 創建登錄視圖
視圖主要用於數據的呈現和交互,登錄視圖對應Login/Index.cshtml頁面。主要功能如下:
- 引入需要的客戶端組件庫。
- 頁面佈局,主要使用Element組件。
- 登錄按鈕功能,主要用axios組件庫,提交數據到控制器。
登錄視圖代碼如下:
1 @{ 2 Layout = null; 3 } 4 <!DOCTYPE html> 5 <html> 6 <head> 7 <title>校園圖書管理系統</title> 8 <!-- For-Mobile-Apps-and-Meta-Tags --> 9 <meta name="viewport" content="width=device-width, initial-scale=1" /> 10 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 11 12 <!-- 引入樣式 --> 13 <link rel="stylesheet" href="/lib/element-ui/theme-chalk/index.min.css"> 14 <!-- 引入組件庫 --> 15 <script src="/lib/vue/dist/vue.min.js"></script> 16 <script src="/lib/element-ui/index.min.js"></script> 17 <script src="/lib/axios/axios.min.js"></script> 18 </head> 19 20 <body style="background:url('/imgs/loginbg.jpg');background-size: 100% 100%;background-repeat:no-repeat;width: 100%;height: 100vh;margin:0;"> 21 22 <div id="app"> 23 <h1>校園圖書管理系統</h1> 24 <div class="loginbody"> 25 <el-form label-width="70px" style="margin-top:40px;" :model="form"> 26 <el-form-item label="用戶名"> 27 <el-input placeholder="Please input username" v-model="form.UserName"/> 28 </el-form-item> 29 <el-form-item label="密碼"> 30 <el-input type="password" placeholder="Please input password" show-password v-model="form.Password"/> 31 </el-form-item> 32 <el-form-item style="text-align:left;"> 33 <el-checkbox label="記住密碼" size="large" v-model="form.Remember" /> 34 </el-form-item> 35 <el-button>取消</el-button> 36 <el-button type="primary" plain v-on:click="onSubmit">登錄</el-button> 37 <br /> 38 <div class="reg"> 39 <el-link type="warning" style="text-align:right;">註冊</el-link> 40 </div> 41 42 </el-form> 43 </div> 44 <br /> 45 <br /> 46 </div> 47 <div class="footer"> 48 <p> © 2022-2023 校園圖書管理系統. All Rights Reserved | Design by 小六公子</p> 49 </div> 50 51 <script> 52 var app= new Vue({ 53 el: '#app', 54 data:function() { 55 return { 56 form: { 57 UserName: '', 58 Password: '', 59 Remember: false, 60 } 61 } 62 }, 63 methods: { 64 onSubmit() { 65 console.log('submit!'); 66 axios.post('/Login/Login', { 67 UserName: this.form.UserName, 68 Password: this.form.Password 69 }).then(function (response) { 70 if(response.status==200){ 71 var msg = response.data; 72 if(msg.code=="0"){ 73 window.location="/Home"; 74 }else{ 75 window.alert(msg.message); 76 } 77 } 78 console.log(response); 79 }).catch(function (error) { 80 console.log(error); 81 }); 82 } 83 } 84 }); 85 </script> 86 <style> 87 #app{ 88 width:100%; 89 height:60%; 90 text-align:center; 91 position:absolute; 92 top:100px; 93 } 94 .el-input{ 95 height:35px; 96 width:90%; 97 } 98 .el-button{ 99 width:120px; 100 height:35px; 101 } 102 .loginbody{ 103 display: block; 104 background: white; 105 width: 25%; 106 height: 300px; 107 position: absolute; 108 left: 38%; 109 border-radius:5px; 110 } 111 .footer{ 112 position: absolute; 113