随着技术的进步,跨平台开发已经成为了标配,在此大背景下,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)
{
}
}
}
运行测试
通过以上步骤,主页面已经开发完成,点击运行进行测试,效果如下所示: