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