• ASP.NET Identity “角色-权限”管理 9


    1.1.       对象映射

    参考1:https://github.com/AutoMapper/AutoMapper

    参考2:AutoMapper的配置方法

    参考3:使用AutoMapper实现Dto和Model的自由转换(上)

    为适应View的变化,将数据封装到ViewModel,从而保持领域模型的纯净稳定,这里使用AutoMapper处理Model与ViewModel之间映射。

    1.1.1.      映射类Profile

    继承自Profile,每个映射类中就是一套对象间映射规则,根据实际需要可设定多套规则。

    [Description("AutoMapper配置")]

    public class AutoMapperProfile : AutoMapper.Profile

    {

        protected override void Configure()

        {

            CreateMap<ApplicationPermission, PermissionViewModel>();

            CreateMap<PermissionViewModel, ApplicationPermission>();

            CreateMap<ApplicationRole, RoleViewModel>();

            CreateMap<RoleViewModel, ApplicationRole>()

                .ForMember(

                            dest => dest.Id,

                            sour =>

                            {

                                sour.MapFrom(s => s.Id ?? System.Guid.NewGuid().ToString());

                            });

               

            CreateMap<ApplicationUser, EditUserViewModel>();

            CreateMap<EditUserViewModel, ApplicationUser>();

            CreateMap<RegisterViewModel, ApplicationUser>();

        }

    }

    1.1.2.      配置类

    加载映射规则,提供静态方法供外部调用。

    [Description("AutoMapper匹配")]

    public class AutoMapperConfig

    {

        public static void Configure()

        {

            AutoMapper.Mapper.Initialize(cfg =>

            {

                cfg.AddProfile<AutoMapperProfile>();

            });

        }

    }

    1.1.3.      修改全局类

    修改Global.asax,MVC启动时加载AutoMapper配置。

    public class MvcApplication : System.Web.HttpApplication

    {

        protected void Application_Start()

        {

            AreaRegistration.RegisterAllAreas();

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            RouteConfig.RegisterRoutes(RouteTable.Routes);

            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //AutoMapper配置

            AutoMapperConfig.Configure();

        }

    }

    1.2.       分页

    参考1:MvcPager概述

    参考2:无废话MVC入门教程八[MvcPager分页控件的使用]

    分页是经常用到的功能,这里采用国内开源控件MvcPager提供的Ajax分页,该控件可通过NuGet安装。

    1.2.1.      Controller

    添加引用Webdiyer.WebControls.Mvc,增加页索引参数Index,返回数据调用ToPagedList(index,pagesize)方法。

    using Webdiyer.WebControls.Mvc;

        // GET: RolesAdmin

        [Description("角色列表")]

        public ActionResult Index(int index = 1)

        {

            var roles = _roleManager.Roles;

            var views = new List<RoleViewModel>();

            foreach (var role in roles)

            {

                var view = Mapper.Map<RoleViewModel>(role);

                views.Add(view);

            }

            return View(views.ToPagedList(index, 10));//显示角色清单

        }

    1.2.2.      View

    同样先添加引用,model类型变更为IPagedList,新建id名为views的div,添加分页参数,增加脚本引用。

    注意:PageIndexParameterName值应与Action的页索引参数一致,UpdateTargetId应于div的id一致。

    @using Webdiyer.WebControls.Mvc

     

    @model IPagedList<AspNetIdentity2Permission.Mvc.Models.RoleViewModel>

    省略页面代码…

    <div id="views">

     

    <table class="table table-hover table-striped">

    省略table代码。。。

        </table>

     

        @Ajax.Pager(Model, new PagerOptions { PageIndexParameterName = "index" }, new MvcAjaxOptions { UpdateTargetId = "views", EnablePartialLoading = true })

    </div>

    @section Scripts{@{Html.RegisterMvcPagerScriptResource();}}

    1.2.3.      运行效果

        整体效果。

        分页效果。

    1.3.       缓存

    1.3.1.      Application

    因反射效率不高,而程序集一旦编译,内部的权限信息是固定不变的,所以将这些信息缓存在Application可提高效率。

    程序集权限信息缓存。

    /// <summary>

    /// 缓存key

    /// </summary>

    const string _permissionKey = "PermissionsOfAssembly";

    /// <summary>

    /// 程序集中权限集合

    /// </summary>

    protected IEnumerable<ApplicationPermission> _permissionsOfAssembly

    {

        get

        {

            //从缓存读取权限信息

            var permissions = HttpContext.Application.Get(_permissionKey)

                                as IEnumerable<ApplicationPermission>;

            if (permissions == null)

            {

                //取程序集中全部权限

                permissions = ActionPermissionService.GetAllActionByAssembly();

                //添加到缓存

                HttpContext.Application.Add(_permissionKey, permissions);

            }

            return permissions;

        }

    }

    1.3.2.      Session

    同理,验证需要频繁访问用户权限,缓存用户-权限亦能提高效率,所以该部分数据保存在Session中。

    /// <summary>

    /// 取当前用户的权限列表

    /// </summary>

    /// <param name="context"></param>

    /// <returns></returns>

    private IEnumerable<ApplicationPermission> GetUserPermissions(HttpContextBase context)

    {

        //取登录名

        var username = context.User.Identity.Name;

        //构建缓存key

        var key = string.Format("UserPermissions_{0}", username);

        //从缓存中取权限

        var permissions = HttpContext.Current.Session[key]

                            as IEnumerable<ApplicationPermission>;

        //若没有,则从db中取并写入缓存

        if (permissions == null)

        {

            //取rolemanager

            var roleManager = context.GetOwinContext().Get<ApplicationRoleManager>();

            //取用户权限集合

            permissions = roleManager.GetUserPermissions(username);

            //写入缓存

            context.Session.Add(key, permissions);

        }

        return permissions;

    }

    1.3.3.      修改登出逻辑

    为避免同一台机器不同用户登录时出现权限混乱,用户登出时要清除Session缓存,修改AccountController.cs中LogOff,登出时清除所有缓存。

    [HttpPost]

    [ValidateAntiForgeryToken]

    public ActionResult LogOff()

    {

        AuthenticationManager.SignOut();

        //移除缓存

        base.HttpContext.Session.RemoveAll();

        return RedirectToAction("Index", "Home");

    }

  • 相关阅读:
    map/reduce/filter/lambda
    DHCP Option43配置
    函数的参数
    通用路由封装协议——GRE
    spring 中使用quartz实现定时任务
    自己实现的简单的grid
    Java 中 Double 相关问题
    爬坑纪——RESTful WCF
    Hi,UEditor——百度编辑器配置若干
    去除ColumnChart自带的阴影效果
  • 原文地址:https://www.cnblogs.com/mlemon/p/4304593.html
Copyright © 2020-2023  润新知