1.1. Permission管理
参考1:Asp.Net大型项目实践(11)-基于MVC Action粒度的权限管理
参考2:ASP.NET MVC三个重要的描述对象:ActionDescriptor
这里Permission指的是Action,即供用户调用的功能。
1.1.1. 新建ApplicationPermission
修改IdentityModel.cs,新增ApplicationPermission,此处设计了属性Id、Controller、Action、Params、Description。
public class ApplicationPermission { public ApplicationPermission() { Id = Guid.NewGuid().ToString(); Roles = new List<ApplicationRolePermission>(); } /// <summary> /// 主键 /// </summary> public string Id { get; set; } /// <summary> /// 控制器名 /// </summary> public string Controller { get; set; } /// <summary> /// 方法名 /// </summary> public string Action { get; set; } /// <summary> /// 参数字符串 /// </summary> public string Params { get; set; } /// <summary> /// 功能描述 /// </summary> public string Description { get; set; } } |
1.1.2. 建立ViewModel
在AdminViewModel.cs中添加PermissionViewModel。
public class PermissionViewModel { /// <summary> /// 主键 /// </summary> [Display(Name = "权限ID")] public string Id { get; set; } /// <summary> /// 控制器名 /// </summary> [Required(AllowEmptyStrings = false)] [Display(Name = "控制器名")] public string Controller { get; set; } /// <summary> /// 方法名 /// </summary> [Required(AllowEmptyStrings = false)] [Display(Name = "方法名")] public string Action { get; set; } /// <summary> /// 功能描述 /// </summary> [Required(AllowEmptyStrings = true)] [Display(Name = "功能描述")] public string Description { get; set; } [Display(Name = "选择")] public bool Selected { get; set; } } |
1.1.3. 自动获取Permission
核心思想:利用反射机制读取各Action的元数据,如:所属Controller、Action名称、参数、功能描述,为此要使用特性Description。
1) 特性Description示例
添加引用System.ComponentModel,为Action添加Description特性。
using System.ComponentModel;
public class UsersAdminController : BaseController {
// GET: UsersAdmin [Description("用户列表")] public async Task<ActionResult> Index() { return View(await _userManager.Users.ToListAsync()); } 省略部分代码… |
2) 读取程序集中Action信息
新建ActionPermissionService.cs,利用MVC中的ReflectedControllerDescriptor与ActionDescriptor获取元数据。
internal static class ActionPermissionService { /// <summary> /// 使用Descriptor,取程序集中所有Action的元数据 /// </summary> /// <returns></returns> public static IEnumerable<ApplicationPermission> GetAllActionByAssembly() { var result = new List<ApplicationPermission>(); //取程序集中的全部类型 var types = Assembly.Load("AspNetIdentity2Permission.Mvc").GetTypes(); //取控制器 foreach (var type in types) { if (type.BaseType == typeof(BaseController))//如果是BaseController { //反射控制器 var controller = new ReflectedControllerDescriptor(type); //取控制器的Action,共有实例方法 var actions = controller.GetCanonicalActions(); //构建权限 foreach (var action in actions) { //创建权限 var ap = new ApplicationPermission() { Action = action.ActionName, Controller = controller.ControllerName, //Params = FormatParams(action), Description = GetDescription(action) }; result.Add(ap); } } } return result; } } |
获取Action的Description特性中的描述信息,因为ActionDescriptor实现了接口ICustomAttributeProvider,所以传入参数类型为接口。
/// <summary> /// 取Action的描述文本 /// </summary> /// <param name="action"></param> /// <returns></returns> public static string GetDescription(ICustomAttributeProvider action) { //取自定义特性数组 var description = action.GetCustomAttributes(typeof(DescriptionAttribute), false); //取出Description,否则为空 var result = description.Length > 0 ? (description[0] as DescriptionAttribute).Description : null; return result; } |
格式化Action的参数。
/// <summary> /// 格式化Action的参数字符串 /// </summary> /// <param name="action"></param> /// <returns></returns> public static string FormatParams(ActionDescriptor action) { var param = action.GetParameters(); var result = new StringBuilder(); if (param.Length > 0) { foreach (var item in param) { result.Append(string.Format("Type:{0}, Name:{1}; ", item.ParameterType, item.ParameterName)); } return result.ToString(); } else { return null; } } |
1.1.4. CRUD管理功能
为Permission添加相应的MVC部件,这里不再累述可参考前面章节。
1.1.5. 运行效果
Index列表
Create新增
编辑
删除