今天把用户的菜单显示和页面的按钮显示都做好了,下面先来个效果图

接下来说下我实现的方法:

首先我在每个方法前面都加了这个属性,

    /// <summary>
/// 表示当前Action请求为一个具体的功能页面
/// </summary>
public class AdminActionMethod : Attribute {
/// <summary>
/// 页面请求路径
/// </summary>
public string ActionUrl { get; set; }
/// <summary>
/// 页面操作代码
/// </summary>
public string RoleCode { get; set; }
/// <summary>
/// 页面返回类型(0:返回页面,1返回json格式)
/// </summary>
public int ActionResultType { get; set; }
}

当不需要验证的时候只要设置RoleCode="NoNeedAuthory"就行。

然后每次在执行方法之间都会进入到

    public class AdminAuthory : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
//用MVC系统自带的功能 获取当前方法上的特性名称
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(NoNeedAdminAuthory), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(NoNeedAdminAuthory), inherit: true);
if (skipAuthorization) {
return;
}
//检查是否登录
if (!WebCookieHelper.AdminCheckLogin()) {
filterContext.Result = new RedirectResult("~/Admin/Account/Login", true);
return;
}
//如果是超级管理就免去验证
if (WebCookieHelper.GetAdminId() == ) {
return;
}
//页面权限验证开始
var customAttributes = filterContext.ActionDescriptor.GetCustomAttributes(true);
if (customAttributes != null && customAttributes.Length > ) {
for (int i = ; i < customAttributes.Count(); i++) {
if (customAttributes.GetValue(i).GetType().Name == "AdminActionMethod") {//判断anction特性名称
string actionCode = (customAttributes[i] as AdminActionMethod).RoleCode;//获取特性功能按钮代码
string actionUrl = (customAttributes[i] as AdminActionMethod).ActionUrl;//获取特性功能地址
int actionResultType = (customAttributes[i] as AdminActionMethod).ActionResultType;//获取返回视图类型
if (actionCode == "NoNeedAuthory") {//不需要权限认证
return;
}
else { //判断权限是否符合
List<AuthorDesign.Model.AdminPageAction> pageActionList = AdminMenuHelper.GetNowAdminMenu();
var pageSelect = pageActionList.Where(m => m.PageUrl == actionUrl);
if (pageSelect != null && pageSelect.Count() > ) { //判断有无执行该页面的权利
//判断有误执行该动作权利
var codeList = AdminMenuHelper.LoadActionCodeList();
//先根据动作按钮代码查找到代码所在按钮Id
var codeSelect = codeList.Where(m => m.ActionCode == actionCode);
if (codeSelect != null && codeSelect.Count() > ) {
int codeId = codeSelect.First().Id;
JavaScriptSerializer serializer = new JavaScriptSerializer();
//判断codeId在角色动作列表中是否为选择状态
string roleActionList = pageSelect.First().RoleActionList; List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel> roleActionListModel = serializer.Deserialize<List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel>>(roleActionList);
if (roleActionListModel != null && roleActionListModel.Where(m => m.ActionId == codeId && m.actionChecked == ).Count() > ) {
//判断CodeId在管理员动作列表中是否为选择状态
List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel> adminActionListModel = serializer.Deserialize<List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel>>(pageSelect.First().AdminActionList);
if (adminActionListModel != null && adminActionListModel.Where(m => m.ActionId == codeId && m.actionChecked == ).Count() > ) {
StringBuilder sb = new StringBuilder();
sb.Append("[");
//传递在该页面可执行的按钮
foreach (var item in roleActionListModel) {
if (item.actionChecked == ) {
var needChangeAction = adminActionListModel.Where(m => m.ActionId == item.ActionId).FirstOrDefault();
if (needChangeAction == null) {
item.actionChecked = ;
}
else if (needChangeAction.actionChecked == ) {
item.actionChecked = ;
}
}
AuthorDesign.Model.PageAction OneAction = codeList.Where(m => m.Id == item.ActionId).FirstOrDefault();
sb.Append("{").Append("\"").Append("ActionName").Append("\"").Append(":").Append("\"").Append(OneAction == null ? "" : OneAction.ActionCode).Append("\"").Append(",").Append("\"").Append("IsChecked").Append("\"").Append(":").Append(item.actionChecked).Append("}").Append(","); }
sb.Remove(sb.Length - , );
sb.Append("]");
filterContext.Controller.ViewBag.CanOperationActionList = sb.ToString();
}
else {
if (actionResultType == ) {
filterContext.Result = new RedirectResult("~/Admin/Home/NoAuthory", true);
}
else if (actionResultType == ) {
filterContext.Result = new JsonResult() { Data = new { state = "error", message = "您暂无权限操作" } };
}
return;
}
}
else {
if (actionResultType == ) {
filterContext.Result = new RedirectResult("~/Admin/Home/NoAuthory", true);
}
else if (actionResultType == ) {
filterContext.Result = new JsonResult() { Data = new { state = "error", message = "您暂无权限操作" } };
}
return;
} }
else {
if (actionResultType == ) {
filterContext.Result = new RedirectResult("~/Admin/Home/NoAuthory", true);
}
else if (actionResultType == ) {
filterContext.Result = new JsonResult() { Data = new { state = "error", message = "您暂无权限操作" } };
}
return;
}
}
else {
if (actionResultType == ) {
filterContext.Result = new RedirectResult("~/Admin/Home/NoAuthory", true);
}
else if (actionResultType == ) {
filterContext.Result = new JsonResult() { Data = new { state = "error", message = "您暂无权限操作" } };
}
return;
}
}
}
}
} base.OnActionExecuting(filterContext);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class NoNeedAdminAuthory : Attribute {
}

这是MVC的机制,这个方法是重写了执行方法之前的这个方法,不过需要在控制器上或者方法上加上下面这个代码

那么接下来就说下我的判断思路:

//检查是否登录
if (!WebCookieHelper.AdminCheckLogin()) {
filterContext.Result = new RedirectResult("~/Admin/Account/Login", true);
return;
}

这是用来先检测下用户是否登录,如果没有登录则直接回到登录页面,

 //如果是超级管理就免去验证
if (WebCookieHelper.GetAdminId() == ) {
return;
}

这是如果进来的用户是超级管理员那么就直接显示要显示的页面页面即可,左边菜单栏晚点讲。

//页面权限验证开始
var customAttributes = filterContext.ActionDescriptor.GetCustomAttributes(true);
if (customAttributes != null && customAttributes.Length > ) {
for (int i = ; i < customAttributes.Count(); i++) {
if (customAttributes.GetValue(i).GetType().Name == "AdminActionMethod") {//判断anction特性名称
string actionCode = (customAttributes[i] as AdminActionMethod).RoleCode;//获取特性功能按钮代码
string actionUrl = (customAttributes[i] as AdminActionMethod).ActionUrl;//获取特性功能地址
int actionResultType = (customAttributes[i] as AdminActionMethod).ActionResultType;//获取返回视图类型

利用这个来抓取用户当前要执行的方法,然后对其作出相应的处理,

 List<AuthorDesign.Model.AdminPageAction> pageActionList = AdminMenuHelper.GetNowAdminMenu();

这行代码用来加载当前要显示的全部页面

        /// <summary>
/// 获取管理员可操作菜单列表
/// </summary>
/// <param name="adminId">管理员Id</param>
/// <returns></returns>
public static List<Model.AdminPageAction> GetAdminMenu(int adminId) {
if (CacheHelper.IsExistCache("AdminMenuList")) {
Dictionary<int, List<Model.AdminPageAction>> adminMenuListDic = CacheHelper.GetCache("AdminMenuList") as Dictionary<int, List<Model.AdminPageAction>>;
List<Model.AdminPageAction> adminMenuList = adminMenuListDic[adminId];
if (adminMenuList == null) {
adminMenuList = EnterRepository.GetRepositoryEnter().GetPageMenuRepository.GetAdminShowPage(adminId);
adminMenuListDic.Add(adminId, adminMenuList);
CacheHelper.AddCache("AdminMenuList", adminMenuListDic, );
}
return adminMenuList;
}
else {
List<Model.AdminPageAction> adminMenuList = EnterRepository.GetRepositoryEnter().GetPageMenuRepository.GetAdminShowPage(adminId);
Dictionary<int, List<Model.AdminPageAction>> adminMenuListDic = new Dictionary<int, List<Model.AdminPageAction>>();
adminMenuListDic.Add(adminId, adminMenuList);
CacheHelper.AddCache("AdminMenuList", adminMenuListDic, );
return adminMenuList;
}
//if (CacheHelper.IsExistCache("AdminMenuList_"+adminId)) {
// return CacheHelper.GetCache("AdminMenuList_" + adminId) as List<Model.AdminPageAction>;
//}
//else {
// List<Model.AdminPageAction> adminMenuList = EnterRepository.GetRepositoryEnter().GetPageMenuRepository.GetAdminShowPage(adminId);
// CacheHelper.AddCache("AdminMenuList_" + adminId, adminMenuList, 1);
// return adminMenuList;
//}
//return EnterRepository.GetRepositoryEnter().GetPageMenuRepository.GetAdminShowPage(adminId);
}
/// <summary>
/// 获取当前管理员可操作菜单列表(超级管理员另取)
/// </summary>
/// <returns></returns>
public static List<Model.AdminPageAction> GetNowAdminMenu() {
return GetAdminMenu(WebCookieHelper.GetAdminId());
}

这里我用缓存做了下处理,不知道处理的好不好,还望你们指点我一下。

 var pageSelect = pageActionList.Where(m => m.PageUrl == actionUrl);
if (pageSelect != null && pageSelect.Count() > ) { //判断有无执行该页面的权利

这个是用来判断当前执行的方法是否在全部要显示的页面之中,如果不是则直接输出,是的话继续往下走。

 //判断有误执行该动作权利
var codeList = AdminMenuHelper.LoadActionCodeList();
//先根据动作按钮代码查找到代码所在按钮Id
var codeSelect = codeList.Where(m => m.ActionCode == actionCode);
if (codeSelect != null && codeSelect.Count() > ) {
int codeId = codeSelect.First().Id;
JavaScriptSerializer serializer = new JavaScriptSerializer();
//判断codeId在角色动作列表中是否为选择状态
string roleActionList = pageSelect.First().RoleActionList;

这里是先判断了当前执行的方法按钮是否在该管理员所属的角色 可操作的按钮之中,不是的话直接输出,如果是的话则继续往下走。

 List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel> roleActionListModel = serializer.Deserialize<List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel>>(roleActionList);
if (roleActionListModel != null && roleActionListModel.Where(m => m.ActionId == codeId && m.actionChecked == ).Count() > ) {
//判断CodeId在管理员动作列表中是否为选择状态
List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel> adminActionListModel = serializer.Deserialize<List<AuthorDesign.Web.Areas.Admin.Models.RolePageActionModel>>(pageSelect.First().AdminActionList);
if (adminActionListModel != null && adminActionListModel.Where(m => m.ActionId == codeId && m.actionChecked == ).Count() > ) {
StringBuilder sb = new StringBuilder();
sb.Append("[");
//传递在该页面可执行的按钮
foreach (var item in roleActionListModel) {
if (item.actionChecked == ) {
var needChangeAction = adminActionListModel.Where(m => m.ActionId == item.ActionId).FirstOrDefault();
if (needChangeAction == null) {
item.actionChecked = ;
}
else if (needChangeAction.actionChecked == ) {
item.actionChecked = ;
}
}
AuthorDesign.Model.PageAction OneAction = codeList.Where(m => m.Id == item.ActionId).FirstOrDefault();
sb.Append("{").Append("\"").Append("ActionName").Append("\"").Append(":").Append("\"").Append(OneAction == null ? "" : OneAction.ActionCode).Append("\"").Append(",").Append("\"").Append("IsChecked").Append("\"").Append(":").Append(item.actionChecked).Append("}").Append(","); }
sb.Remove(sb.Length - , );
sb.Append("]");
filterContext.Controller.ViewBag.CanOperationActionList = sb.ToString();

这部分就是主要用来判断当前执行的方法是否在该管理员可执行的按钮之中,如果在的话那么将改页面的按钮以及是否可操作状态通过ViewBag进行传到前台,然后前台利用Js来移除相对应的不显示按钮。

左边的菜单按钮部分待会上源码自己去看下吧

那么简单的用户角色权限管理在这里就可以结束了。但是我发现有个问题,我也不知道是为什么:看下面

就是我用火狐的时候,发现点击某些链接的时候会不经过那个action的方法,直接跳到登录页面,这是为什么,我碰到好几次了,求帮忙解决下。

百度源码下载地址

github地址:https://github.com/yjqGitHub/AuthoryDesign

有什么地方写的不好的还希望大家都指出来啊

Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理10的更多相关文章

  1. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理

    这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...

  2. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理4

    首先先加个区域,名为Admin using System.Web.Mvc; namespace AuthorDesign.Web.Areas.Admin { public class AdminAre ...

  3. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理9

    前两天因有事就没来得及写.今天刚刚好空了.这次写的是对角色和管理员对页面按钮之间的控制.先看页面效果 说明:先根据角色设置好角色的权限,然后管理员在对应的角色下的权限去设置其权限. 在设置角色权限的时 ...

  4. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理6

    接下来先做角色这一板块的(增删改查),首先要新建一个Role控制器,在添加一个RoleList的视图.表格打算采用的是bootstrap的表格. using System; using System. ...

  5. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理5

    我们先直接拷贝下blank.html这个页面的代码,顺带先建立一个Home控制器,并添加Index视图.将代码拷贝进去. <!DOCTYPE html> <html lang=&qu ...

  6. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理7

    做完角色之后接下来做先做页面按钮的增加.删除.修改.这里用到的功能和角色那边是一样的.就不多说了.直接上代码. 后台控制器代码 using AuthorDesign.Web.App_Start.Com ...

  7. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理8

    接下来做的是对页面的增删改查与页面与页面按钮之间的联系.先上代码和页面效果 using AuthorDesign.Web.App_Start.Common; using System; using S ...

  8. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理1

    首先给上项目的整体框架图:,这里我没有使用BLL,因为感觉太烦了就没有去使用. 那么接下来我们首先先去Model层中添加Model. 管理员类: using System; using System. ...

  9. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理3

    首先在webconfig中加入下面这句代码,这个主要是用来生成数据库的连接字符串 <connectionStrings> <add name="AuthorDesignCo ...

随机推荐

  1. CSS魔法堂:"那不是bug,是你不懂我!" by inline-block

    前言  每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;.然后发 ...

  2. Xamarin.Android之简单的抽屉布局

    0x01 前言 相信对于用过Android版QQ的,应该都不会陌生它那个向右滑动的菜单(虽说我用的是Lumia) 今天就用Xamarin.Android实现个比较简单的抽屉布局.下面直接进正题. 0x ...

  3. package.json for npm中依赖外部组件时常用的版本符号含义

    package.json中会有dependencies定义了项目依赖的外部组件,这些外部组件的依赖都是带有版本符号以表示被依赖组件的版本范围. { "dependencies" : ...

  4. [WCF编程]12.事务:服务事务编程(下)

    一.投票与提交 虽然WCF负责事务传播及两阶段提交协议的管理工作,但是 她不知道事务是否应该提交或终止.这需要根服务告诉WCF应该何时启动两阶段提交协议.是提交还是终止.WCF提供了两种编程模式来对事 ...

  5. NoSQL

    Not Only Sql,弱一致性模型,非关系型.分布式.支持水平扩展的数据库设计模式,区别于传统关系型数据库严格的事务一致性和范式约束.分布式缓存是NoSQL一种实现形式. 参考:

  6. 在多行列表中id同名的<a>标签点击事件处理方法

    Struts2标签 问题描述:最近项目中在使用struts迭代标签动态生成列表的过程中,由于每一行li元素中包含<a>超链接,如下图 一开始超链接是这样的<a href=“#” id ...

  7. 解决WIN7与虚拟机CentOS的文件夹共享问题

    一.系统与软件 WIN7 64bit.VirtualBox 5.0.14.CentOS 6.5.SecureCRT 7.2.3 二.使用文件夹共享需要安装增强功能,但是安装时无法读取光盘iso文件 三 ...

  8. c++函数模板作为类的成员函数,编译报错LNK2019的解决方法

    为了使某个类的成员函数能对不同的参数进行相同的处理,需要用到函数模板,即template<typename T> void Function(). 编译时报错LNK2019 解决方法: 1 ...

  9. 【Java学习系列】第1课--Java环境搭建和demo运行

    本文地址 分享提纲: 1. java环境的搭建 2. java demo代码运行 3.参考文档 本人是PHP开发者,一直感觉Java才是程序的王道(应用广,科班出身),所以终于下决心跟一跟. 主要是给 ...

  10. mysql errno 150

    mysql error Number 1005can't creat table'/test/#sql-640_1.frm'(errno:150)三种可能问题 外键和被引用外键类型不一样,比如inte ...