随着技术的进步,跨平台开发已经成为了标配,在此大背景下,ASP.NET Core也应运而生。本文主要利用ASP.NET Core开发一个学生管理系统为例,简述ASP.NET Core开发的常见知识点,前一篇文章做了登录功能,本文继续分享开发主页面功能。仅供学习分享使用,如有不足之处,还请指正。
涉及知识点
开发学生管理系统,涉及知识点,如下所示:
- 开发工具:Visual Studio 2019
- 目标框架:.Net 5.0
- 架构:MVC三层架构【Model-View-Controller】
页面布局
主页面中主要分为三部分上【header】,中【左侧菜单栏,右侧内容区域】,下【footer】,示意图如下所示:
创建模型
在主页面,左侧的菜单需要根据不同的用户进行不同的显示,所以需要创建菜单-用户-角色对应的模型,如下所示:
1. 菜单【Menu】模型
Menu模型,如下所示:
namespace SMS.Models { /// <summary> /// 菜单管理 /// </summary> public class Menu { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 菜单名称 /// </summary> public string Name { get; set; } /// <summary> /// 菜单描述 /// </summary> public string Description { get; set; } /// <summary> /// 菜单路径 /// </summary> public string Url { get; set; } /// <summary> /// 父ID /// </summary> public int? ParentId { get; set; } /// <summary> /// 排序 /// </summary> public int? SortId { get; set; } } }
2. 角色【Role】模型
角色模型,如下所示:
namespace SMS.Models { /// <summary> /// 角色 /// </summary> public class Role { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 角色名称 /// </summary> public string Name { get; set; } /// <summary> /// 角色描述 /// </summary> public string Description { get; set; } } }
3. 角色-菜单关联模型
角色-菜单关联模型【RoleMenu】,主要是将角色和菜单关联起来,如下所示:
namespace SMS.Models { /// <summary> /// 角色-菜单关联 /// </summary> public class RoleMenu { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 菜单IP /// </summary> public int MenuId { get; set; } /// <summary> /// 角色ID /// </summary> public int RoleId { get; set; } } }
4. 用户-角色模型
用户-角色模型,主要是将用户和角色关联起来,如下所示:
namespace SMS.Models { /// <summary> /// 用户-角色模型 /// </summary> public class UserRole { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 用户ID /// </summary> public int UserId { get; set; } /// <summary> /// 角色ID /// </summary> public int RoleId { get; set; } } }
5. 用户权限模型
将以上几种模型,查询出来就是用户所具备的权限,所以需要创建用户权限模型,如下所示:
namespace SMS.Models { /// <summary> /// 用户-权限模型 /// </summary> public class UserRight { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 角色名称 /// </summary> public string RoleName { get; set; } /// <summary> /// 菜单名称 /// </summary> public string MenuName { get; set; } /// <summary> /// 路径 /// </summary> public string Url { get; set; } /// <summary> /// 父ID /// </summary> public int? ParentId { get; set; } /// <summary> /// 排序 /// </summary> public int? SortId { get; set; } } }
创建控制器
主页面默认采用HomeController,如下所示:
namespace SMS.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private DataContext dataContext; public HomeController(ILogger<HomeController> logger, DataContext context) { _logger = logger; dataContext = context; } public IActionResult Index() { int? userId = HttpContext.Session.GetInt32("UserId"); //判断是否登录 if (userId != null) { var user = dataContext.Users.FirstOrDefault(u=>u.Id== userId); if (user != null) { ViewBag.NickName = user.NickName; ViewBag.UserRights = GetUserRights(); } return View(); } else { return Redirect("/Login"); } } public IActionResult Privacy() { return View(); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } public List<UserRight> GetUserRights() { int? userId = HttpContext.Session.GetInt32("UserId"); if (userId != null) { var query = from u in dataContext.UserRoles join r in dataContext.Roles on u.RoleId equals r.Id join x in dataContext.RoleMenus on r.Id equals x.RoleId join m in dataContext.Menus on x.MenuId equals m.Id where u.UserId == userId select new UserRight { Id=m.Id, RoleName = r.Name, MenuName = m.Name, Url = m.Url, ParentId = m.ParentId, SortId=m.SortId }; return query.ToList(); } return null; } } }
创建视图
主页面视图,位于Views/Home/Index.cshtml,如下所示:
@{ Layout = null; } <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>学生信息管理系统</title> <link rel="stylesheet" type="text/css" href="/css/reset.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/text.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/grid.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/layout.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/nav.css" media="screen" /> <!--[if IE 6]><link rel="stylesheet" type="text/css" href="css/ie6.css" media="screen" /><![endif]--> <!--[if IE 7]><link rel="stylesheet" type="text/css" href="css/ie.css" media="screen" /><![endif]--> <!-- BEGIN: load jquery --> <script src="js/jquery-1.6.4.min.js" type="text/javascript"></script> <script type="text/javascript" src="/js/jquery-ui/jquery.ui.core.min.js"></script> <script src="/js/jquery-ui/jquery.ui.widget.min.js" type="text/javascript"></script> <script src="/js/jquery-ui/jquery.ui.accordion.min.js" type="text/javascript"></script> <script src="/js/jquery-ui/jquery.effects.core.min.js" type="text/javascript"></script> <script src="/js/jquery-ui/jquery.effects.slide.min.js" type="text/javascript"></script> <!-- END: load jquery --> <script src="/js/setup.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { //setupDashboardChart('chart1'); setupLeftMenu(); setSidebarHeight(); }); </script> <style type="text/css"> #demo-side-bar { left: 90% !important; display: block !important; } #branding .floatright { margin-right: 130px !important; } </style> </head> <body> <div class="container_12"> <div class="grid_12 header-repeat"> <div id="branding"> <div class="floatleft"> <h2 style="color:white;margin-top:unset;">学生信息管理系统</h2> <br /> </div> <div class="floatright"> <div class="floatleft"> <img src="img/img-profile.jpg" alt="Profile Pic" /> </div> <div class="floatleft marginleft10"> <ul class="inline-ul floatleft"> <li>Hello <a href="#">@ViewBag.NickName</a></li> <li><a href="#">Logout</a></li> </ul> <br /> <span class="small grey">上次登录: 3 小时前</span> </div> </div> <div class="clear"> </div> </div> </div> <div class="clear"> </div> <div class="grid_12"> <ul class="nav main"> <li class="ic-dashboard"><a href="#"><span>首页</span></a> </li> <li class="ic-form-style"> <a href="javascript:"><span>学生管理</span></a> <ul> <li><a href="form-controls.html">学生信息</a> </li> </ul> </li> <li class="ic-form-style"> <a href="javascript:"><span>成绩管理</span></a> <ul> <li><a href="form-controls.html">成绩信息</a> </li> </ul> </li> <li class="ic-notifications"><a href="notifications.html"><span>Notifications</span></a></li> </ul> </div> <div class="clear"> </div> <div class="grid_2"> <div class="box sidemenu"> <div class="block" id="section-menu"> <ul class="section menu"> @{ var UserRights = ViewBag.UserRights as List<UserRight>; //先取出一级菜单 var menuItems = UserRights.Where((u) => u.ParentId == null).OrderBy(u => u.SortId); foreach (var menuItem in menuItems) { <li> <a class="menuitem">@menuItem.MenuName</a> <ul class="submenu"> @{ var sumMenuItems = UserRights.Where(s => s.ParentId == menuItem.Id).OrderBy(s => s.SortId); foreach (var subMenuItem in sumMenuItems) { <li><a href="@subMenuItem.Url">@subMenuItem.MenuName</a> </li> } } </ul> </li> } } </ul> </div> </div> </div> <div class="grid_10" style="height:600px;"> <iframe width="100%" height="100%"> </iframe> </div> <div class="clear"> </div> </div> <div class="clear"> </div> <div id="site_info"> <p style="text-align:center"> Copyright <a href="#">学生信息管理系统</a>. All Rights Reserved By 小六公子. 2021-2022 </p> </div> </body> </html>
构建数据
在示例中,需要构建数据,用于显示菜单信息,数据表结构和模型保持一致。
1. 菜单表
菜单表,表结构及初始化数据,如下所示:
2. 角色表
角色表,表结构和初始化数据,如下所示:
3. 角色-菜单表
角色-菜单表,表示角色和菜单之间的对应关系。数据表结构和初始化数据,如下所示:
4. 用户-角色表
用户-角色表,主要用于配置用户ID和角色ID之间的对应关系,表结构和初始化数据,如下所示:
数据库集成DbContext
在示例中,通过Entity Framework Core来操作数据库,如下所示:
namespace SMS.Models { public class DataContext:DbContext { public DbSet<User> Users { get; set; } public DbSet<Menu> Menus { get; set; } public DbSet<Role> Roles { get; set; } public DbSet<UserRole> UserRoles { get; set; } public DbSet<RoleMenu> RoleMenus { get; set; } public DataContext(DbContextOptions options) : base(options) { } } }
运行测试
通过以上步骤,主页面已经开发完成,点击运行进行测试,效果如下所示:
备注
本示例主要介绍学生信息管理系统的主页面开发,其他功能,后续继续更新,旨在抛砖引玉,一起学习,共同进步。关于示例源码,可点击下载
蝶恋花·欲减罗衣寒未去【作者】赵令畤 【朝代】宋
欲减罗衣寒未去,不卷珠帘,人在深深处。残杏枝头花几许。啼红正恨清明雨。
尽日沈香烟一缕。宿酒醒迟,恼破春情绪。远信还因归燕误。小屏风上西江路。