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");

}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。