隨著技術(shù)的進(jìn)步,跨平臺開發(fā)已經(jīng)成為了標(biāo)配,在此大背景下,ASP.NET Core也應(yīng)運(yùn)而生。本文主要利用ASP.NET Core開發(fā)一個(gè)學(xué)生管理系統(tǒng)為例,簡述ASP.NET Core開發(fā)的常見知識點(diǎn),前一篇文章做了登錄功能,本文繼續(xù)分享開發(fā)主頁面功能。僅供學(xué)習(xí)分享使用,如有不足之處,還請指正。
開發(fā)學(xué)生管理系統(tǒng),涉及知識點(diǎn),如下所示:
開發(fā)工具:Visual Studio 2019
目標(biāo)框架:.Net 5.0
架構(gòu):MVC三層架構(gòu)【Model-View-Controller】
主頁面中主要分為三部分上【header】,中【左側(cè)菜單欄,右側(cè)內(nèi)容區(qū)域】,下【footer】,示意圖如下所示:
在主頁面,左側(cè)的菜單需要根據(jù)不同的用戶進(jìn)行不同的顯示,所以需要?jiǎng)?chuàng)建菜單-用戶-角色對應(yīng)的模型,如下所示:
Menu模型,如下所示:
namespace SMS.Models
{
/// <summary>
/// 菜單管理
/// </summary>
public class Menu
{
/// <summary>
/// 唯一標(biāo)識
/// </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; }
}
}
角色模型,如下所示:
namespace SMS.Models
{
/// <summary>
/// 角色
/// </summary>
public class Role
{
/// <summary>
/// 唯一標(biāo)識
/// </summary>
public int Id { get; set; }
/// <summary>
/// 角色名稱
/// </summary>
public string Name { get; set; }
/// <summary>
/// 角色描述
/// </summary>
public string Description { get; set; }
}
}
角色-菜單關(guān)聯(lián)模型【RoleMenu】,主要是將角色和菜單關(guān)聯(lián)起來,如下所示:
namespace SMS.Models
{
/// <summary>
/// 角色-菜單關(guān)聯(lián)
/// </summary>
public class RoleMenu
{
/// <summary>
/// 唯一標(biāo)識
/// </summary>
public int Id { get; set; }
/// <summary>
/// 菜單IP
/// </summary>
public int MenuId { get; set; }
/// <summary>
/// 角色I(xiàn)D
/// </summary>
public int RoleId { get; set; }
}
}
用戶-角色模型,主要是將用戶和角色關(guān)聯(lián)起來,如下所示:
namespace SMS.Models
{
/// <summary>
/// 用戶-角色模型
/// </summary>
public class UserRole
{
/// <summary>
/// 唯一標(biāo)識
/// </summary>
public int Id { get; set; }
/// <summary>
/// 用戶ID
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 角色I(xiàn)D
/// </summary>
public int RoleId { get; set; }
}
}
將以上幾種模型,查詢出來就是用戶所具備的權(quán)限,所以需要?jiǎng)?chuàng)建用戶權(quán)限模型,如下所示:
namespace SMS.Models
{
/// <summary>
/// 用戶-權(quán)限模型
/// </summary>
public class UserRight
{
/// <summary>
/// 唯一標(biāo)識
/// </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; }
}
}
主頁面默認(rèn)采用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>學(xué)生信息管理系統(tǒng)</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;">學(xué)生信息管理系統(tǒng)</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 小時(shí)前</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>學(xué)生管理</span></a>
<ul>
<li><a href="form-controls.html">學(xué)生信息</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="#">學(xué)生信息管理系統(tǒng)</a>. All Rights Reserved By 小六公子. 2021-2022
</p>
</div>
</body>
</html>
在示例中,需要構(gòu)建數(shù)據(jù),用于顯示菜單信息,數(shù)據(jù)表結(jié)構(gòu)和模型保持一致。
菜單表,表結(jié)構(gòu)及初始化數(shù)據(jù),如下所示:
角色表,表結(jié)構(gòu)和初始化數(shù)據(jù),如下所示:
角色-菜單表,表示角色和菜單之間的對應(yīng)關(guān)系。數(shù)據(jù)表結(jié)構(gòu)和初始化數(shù)據(jù),如下所示:
用戶-角色表,主要用于配置用戶ID和角色I(xiàn)D之間的對應(yīng)關(guān)系,表結(jié)構(gòu)和初始化數(shù)據(jù),如下所示:
在示例中,通過Entity Framework Core來操作數(shù)據(jù)庫,如下所示:
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)
{
}
}
}
通過以上步驟,主頁面已經(jīng)開發(fā)完成,點(diǎn)擊運(yùn)行進(jìn)行測試,效果如下所示:
本示例主要介紹學(xué)生信息管理系統(tǒng)的主頁面開發(fā),其他功能,后續(xù)繼續(xù)更新,旨在拋磚引玉,一起學(xué)習(xí),共同進(jìn)步。
學(xué)習(xí)編程,從關(guān)注【老碼識途】開始
聯(lián)系客服