番外篇--Moddule Zero安装
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期
Moddule Zero
安装
1.2.1 从模板创建
使用ABP和module-zero开始一个新项目最简单的方式是使用启动模板。详细了解请参考启动模板文档。
1.2.2 手动安装
如果你有一个预先创建的应用程序,稍后再安装module-zero,您可以按照本部分的说明。
在本文中,我将假定您的解决方案具有以下项目:
AbpZeroSample.Core
AbpZeroSample.Application
AbpZeroSample.EntityFramework
AbpZeroSample.Web
AbpZeroSample.WebApi
1.2.3 核心(领域)层
安装Abp.Zero的NuGet包到时Core工程。然后进入到核心模块类(在此示例中为AbpZeroSampleCoreModule类),并添加DependsOn属性AbpZeroCoreModule如下图所示:
[DependsOn(typeof(AbpZeroCoreModule))]
public class AbpZeroSampleCoreModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
1.2.4 领域类(实体)
Module-zero提供了 User,Role和Tenant 类的抽象。所以,我们应该实现它们,如下所示:
public class User : AbpUser<Tenant, User>
{
}
public class Role : AbpRole<Tenant, User>
{
}
public class Tenant : AbpTenant<Tenant, User>
{
}
你可以在这里添加自定义属性。通过这种方式,我们可以根据我们的需要扩展基用户,角色和租户类。
1.2.5 管理类(领域服务)
我们应该先实现管理基类和存储基类,因为他们是抽象的。
从启动用户存储和用户管理开始:
public class UserStore : AbpUserStore<Tenant, Role, User>
{
public UserStore(
IRepository<User, long> userRepository,
IRepository<UserLogin, long> userLoginRepository,
IRepository<UserRole, long> userRoleRepository,
IRepository<Role> roleRepository,
IRepository<UserPermissionSetting, long> userPermissionSettingRepository,
IUnitOfWorkManager unitOfWorkManager
)
: base(
userRepository,
userLoginRepository,
userRoleRepository,
roleRepository,
userPermissionSettingRepository,
unitOfWorkManager
)
{
}
}
public class UserManager : AbpUserManager<Tenant, Role, User>
{
public UserManager(
UserStore userStore,
RoleManager roleManager,
IRepository<Tenant> tenantRepository,
IMultiTenancyConfig multiTenancyConfig,
IPermissionManager permissionManager,
IUnitOfWorkManager unitOfWorkManager,
ISettingManager settingManager,
IUserManagementConfig userManagementConfig,
IIocResolver iocResolver,
ICacheManager cacheManager,
IRepository<OrganizationUnit, long> organizationUnitRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IOrganizationUnitSettings organizationUnitSettings)
: base(
userStore,
roleManager,
tenantRepository,
multiTenancyConfig,
permissionManager,
unitOfWorkManager,
settingManager,
userManagementConfig,
iocResolver,
cacheManager,
organizationUnitRepository,
userOrganizationUnitRepository,
organizationUnitSettings)
{
}
}
别担心依赖列表。他们可能会在下一个版本改变。如果需要的话只是组织构造函数。角色存储和角色管理也类似:
public class RoleStore : AbpRoleStore<Tenant, Role, User>
{
public RoleStore(
IRepository<Role> roleRepository,
IRepository<UserRole, long> userRoleRepository,
IRepository<RolePermissionSetting, long> rolePermissionSettingRepository)
: base(
roleRepository,
userRoleRepository,
rolePermissionSettingRepository
)
{
}
}
public class RoleManager : AbpRoleManager<Tenant, Role, User>
{
public RoleManager(
RoleStore store,
IPermissionManager permissionManager,
IRoleManagementConfig roleManagementConfig,
ICacheManager cacheManager)
: base(
store,
permissionManager,
roleManagementConfig,
cacheManager)
{
}
}
最后,我们要创建一个类租户管理类(这里没有租户存储):
public class TenantManager : AbpTenantManager<Tenant, Role, User>
{
public TenantManager(
IRepository<Tenant> tenantRepository,
IRepository<TenantFeatureSetting, long> tenantFeatureRepository,
EditionManager editionManager) :
base(
tenantRepository,
tenantFeatureRepository,
editionManager
)
{
}
}
最后是功能值存储类以及版本管理类:
public class FeatureValueStore : AbpFeatureValueStore<Tenant, Role, User>
{
public FeatureValueStore(TenantManager tenantManager)
: base(tenantManager)
{
}
}
public class EditionManager : AbpEditionManager
{
public const string DefaultEditionName = "Standard";
public EditionManager(
IRepository<Edition> editionRepository,
IRepository<EditionFeatureSetting, long> editionFeatureRepository)
: base(
editionRepository,
editionFeatureRepository
)
{
}
}
1.2.6 权限检查器
为了使授权系统工作,我们应该实现权限检查器:
public class PermissionChecker : PermissionChecker<Tenant, Role, User>
{
public PermissionChecker(UserManager userManager)
: base(userManager)
{
}
}
1.2.7 基础设施层
1. Entity Framework
如果您选择Entity Framework,我们应该配置它以便使用module-zero。安装Abp.Zero.EntityFramework的NuGet包到EntityFramework项目。然后进入到模块文件(此示例中为AbpZeroSampleDataModule)和改变AbpEntityFrameworkModule依赖到AbpZeroEntityFrameworkModule如下图所示:
[DependsOn(typeof(AbpZeroEntityFrameworkModule), typeof(AbpZeroSampleCoreModule))]
public class AbpZeroSampleDataModule : AbpModule
{
//...
}
2. DbContext
转到您的DbContext类,并改变基类AbpDbContext为AbpZeroDbContext;如下所示:
public class AbpZeroSampleDbContext : AbpZeroDbContext<Tenant, Role, User>
{
//...
}
从而,module-zero里的基础实体被添加到你的数据库环境中。
3. 数据库迁移
现在,我们应该创建数据库迁移,因为我们的数据库上下文被更改了。打开包管理器控制台,然后键入以下命令:
Add-Migration "AbpZero_Installed"
当然,你可以选择不同的迁移名称。不要忘了在包管理器控制台中选择默认工程为AbpZeroSample.EntityFramework(对于你的例子AbpZeroSample将是不同的)。执行这个命令之后,一个新的迁移文件被添加到工程中。检查它,如果你需要可以改变它。然后键入以下命令来更新数据库模式:
Update-Database
您可以检查EntityFramework的代码优先迁移文档以获取更多信息。
4. 初始化数据
如果你检查你的数据库,你会看到表已经被创建,但它们是空的。您可以使用EntityFramework的播种以填补初始数据。您可以使用这样的类作为初始数据生成器:
public class DefaultTenantRoleAndUserBuilder
{
private readonly AbpZeroSampleDbContext _context;
public DefaultTenantRoleAndUserBuilder(AbpZeroSampleDbContext context)
{
_context = context;
}
public void Build()
{
CreateUserAndRoles();
}
private void CreateUserAndRoles()
{
//Admin role for tenancy owner
var adminRoleForTenancyOwner = _context.Roles.FirstOrDefault(r => r.TenantId == null && r.Name == "Admin");
if (adminRoleForTenancyOwner == null)
{
adminRoleForTenancyOwner = _context.Roles.Add(new Role {Name = "Admin", DisplayName = "Admin"});
_context.SaveChanges();
}
//Admin user for tenancy owner
var adminUserForTenancyOwner = _context.Users.FirstOrDefault(u => u.TenantId == null && u.UserName == "admin");
if (adminUserForTenancyOwner == null)
{
adminUserForTenancyOwner = _context.Users.Add(
new User
{
TenantId = null,
UserName = "admin",
Name = "System",
Surname = "Administrator",
EmailAddress = "admin@aspnetboilerplate.com",
IsEmailConfirmed = true,
Password = "AM4OLBpptxBYmM79lGOX9egzZk3vIQU3d/gFCJzaBjAPXzYIK3tQ2N7X4fcrHtElTw==" //123qwe
});
_context.SaveChanges();
_context.UserRoles.Add(new UserRole(adminUserForTenancyOwner.Id, adminRoleForTenancyOwner.Id));
_context.SaveChanges();
}
//Default tenant
var defaultTenant = _context.Tenants.FirstOrDefault(t => t.TenancyName == "Default");
if (defaultTenant == null)
{
defaultTenant = _context.Tenants.Add(new Tenant {TenancyName = "Default", Name = "Default"});
_context.SaveChanges();
}
//Admin role for 'Default' tenant
var adminRoleForDefaultTenant = _context.Roles.FirstOrDefault(r => r.TenantId == defaultTenant.Id && r.Name == "Admin");
if (adminRoleForDefaultTenant == null)
{
adminRoleForDefaultTenant = _context.Roles.Add(new Role { TenantId = defaultTenant.Id, Name = "Admin", DisplayName = "Admin" });
_context.SaveChanges();
}
//Admin for 'Default' tenant
var adminUserForDefaultTenant = _context.Users.FirstOrDefault(u => u.TenantId == defaultTenant.Id && u.UserName == "admin");
if (adminUserForDefaultTenant == null)
{
adminUserForDefaultTenant = _context.Users.Add(
new User
{
TenantId = defaultTenant.Id,
UserName = "admin",
Name = "System",
Surname = "Administrator",
EmailAddress = "admin@aspnetboilerplate.com",
IsEmailConfirmed = true,
Password = "AM4OLBpptxBYmM79lGOX9egzZk3vIQU3d/gFCJzaBjAPXzYIK3tQ2N7X4fcrHtElTw==" //123qwe
});
_context.SaveChanges();
_context.UserRoles.Add(new UserRole(adminUserForDefaultTenant.Id, adminRoleForDefaultTenant.Id));
_context.SaveChanges();
}
}
}
该类创建默认租户,角色和用户。我们可以用它在EF的配置类中初始化我们的数据库数据:
internal sealed class Configuration : DbMigrationsConfiguration<AbpZeroSample.EntityFramework.AbpZeroSampleDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
ContextKey = "AbpZeroSample";
}
protected override void Seed(AbpZeroSample.EntityFramework.AbpZeroSampleDbContext context)
{
context.DisableAllFilters();
new DefaultTenantRoleAndUserBuilder(context).Build();
}
}
在这里,我们禁用数据过滤器(所以我们可以自由地操纵数据库),并使用的初始数据生成器类。
1.2.8 表示层
1. NuGet包
添加以下的NuGet包到.Web工程:
Abp.Zero.EntityFramework(这也将增加Abp.Zero和所有的依赖)
Microsoft.AspNet.Identity.Owin
Microsoft.Owin.Host.SystemWeb
2. Owin启动类
添加这样一个Owin启动类:
using AbpZeroSample.Web;
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
[assembly: OwinStartup(typeof(Startup))]
namespace AbpZeroSample.Web
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//对当前应用开启cookie功能,使用它来存储已登录的用户信息
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
//使用cookie来临时性的存储一个已经登录的用户信息,该登录配置的是使用第三方登录提供器
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
}
}
3. 账户控制器
我们可以创建一个控制器用于登录/注销,如下所示:
public class AccountController : AbpZeroSampleControllerBase
{
private readonly UserManager _userManager;
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
public AccountController(UserManager userManager)
{
_userManager = userManager;
}
public ActionResult Login(string returnUrl = "")
{
if (string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = Request.ApplicationPath;
}
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
public async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "")
{
if (!ModelState.IsValid)
{
throw new UserFriendlyException("Your form is invalid!");
}
var loginResult = await _userManager.LoginAsync(
loginModel.UsernameOrEmailAddress,
loginModel.Password,
loginModel.TenancyName
);
switch (loginResult.Result)
{
case AbpLoginResultType.Success:
break;
case AbpLoginResultType.InvalidUserNameOrEmailAddress:
case AbpLoginResultType.InvalidPassword:
throw new UserFriendlyException("Invalid user name or password!");
case AbpLoginResultType.InvalidTenancyName:
throw new UserFriendlyException("No tenant with name: " + loginModel.TenancyName);
case AbpLoginResultType.TenantIsNotActive:
throw new UserFriendlyException("Tenant is not active: " + loginModel.TenancyName);
case AbpLoginResultType.UserIsNotActive:
throw new UserFriendlyException("User is not active: " + loginModel.UsernameOrEmailAddress);
case AbpLoginResultType.UserEmailIsNotConfirmed:
throw new UserFriendlyException("Your email address is not confirmed!");
default: //Can not fall to default for now. But other result types can be added in the future and we may forget to handle it
throw new UserFriendlyException("Unknown problem with login: " + loginResult.Result);
}
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = loginModel.RememberMe }, loginResult.Identity);
if (string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = Request.ApplicationPath;
}
return Json(new MvcAjaxResponse { TargetUrl = returnUrl });
}
public ActionResult Logout()
{
AuthenticationManager.SignOut();
return RedirectToAction("Login");
}
}
附一个简单的LoginViewModel:
public class LoginViewModel
{
public string TenancyName { get; set; }
[Required]
public string UsernameOrEmailAddress { get; set; }
[Required]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
1.2.9 登录视图
为了能够使用的AccountController,我们应该创建一个登录页面。这由你决定创建一个登录表单。只需通过AJAX使用适当的参数调用AccountController.Login。
1. 确保应用程序安全
现在,我们可以添加一个AbpAuthorize特性到HomeController,以确保只有合法的用户才能进入到页面:
[AbpMvcAuthorize]
public class HomeController : AbpZeroSampleControllerBase
{
public ActionResult Index()
{
return View("~/App/Main/views/layout/layout.cshtml"); //Layout of the angular application.
}
番外篇--Moddule Zero安装的更多相关文章
- 番外篇--Moddule Zero多租户管理
番外篇--Moddule Zero多租户管理 2.1.1 关于多租户 强烈建议阅读这个文件前阅读多租户文档. 2.1.2 启用多租户 ASP.NET Boilerplate和module-zero可以 ...
- 番外篇--Moddule Zero 版本管理与组织单位管理
Moddule Zero 版本管理 2.2.1 简介 大多数SaaS(多租户)应用都会有多个版本(包),这些版本的功能点也会各不相同.因此,他们能够为他们的租户(客户)提供不同的价格和功能点选项. 关 ...
- 番外篇--Moddule Zero启动模板
1.3 ABPZero - 启动模板 1.3.1 简介 使用ABP和moudle-zero开始一个新项目的最简单的方式是在模板页创建模板.记住要勾选 Include module zero. 在创建并 ...
- 番外篇--Moddule Zero介绍
1.1 ABPZero - 概述 介绍 微软ASP.NET身份框架 权限 会话 角色管理 默认角色 用户管理 多租户 设置管理 审计日志 1.1.1 介绍 Modulde Zero实现了ASP.NET ...
- 番外篇1:在Windows环境中安装JDK
他山之石,可以攻玉!欢迎关注我的微信公众号 本文作为构建第一个Java程序的番外篇一,跟大家探讨下在Windows下怎么安装JDK.由于本人没有Mac,因此如果是Mac的同学,请自行百度哦! 读前预览 ...
- iOS冰与火之歌(番外篇) - 基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权
iOS冰与火之歌(番外篇) 基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权 蒸米@阿里移动安全 0x00 序 这段时间最火的漏洞当属阿联酋的人权活动人士被apt攻击所使用 ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- 可视化(番外篇)——SWT总结
本篇主要介绍如何在SWT下构建一个应用,如何安装SWT Designer并破解已进行SWT的可视化编程,Display以及Shell为何物.有何用,SWT中的常用组件.面板容器以及事件模型等. 1.可 ...
- C++雾中风景番外篇:理解C++的复杂声明与声明解析
在学习C系列语言的过程之中,理解C/C++的复杂声明一直是初学者很困扰的问题.笔者初学之时也深受困扰,对很多规则死记硬背.后续在阅读<C专家编程>之后,尝试在编译器的角度来理解C/C++的 ...
随机推荐
- Delete 命令详解
cp:复制文件 /cp -r:复制目录 /bin/cp -f: 复制文件并覆盖已有文件(写命令的绝对路径/bin/) /cp /ect/passwd .:将其他文件复制到当前目录 /-n :不要 ...
- input上传图片(file),预览图片的两种方法。blob与base64编码
上传图片时一般都需要预览,我一般用这两种方法来实现.base64编码可以直接上传到后台,后台解析下,得到的文件就会比较小了,省去了压缩图片这一步了. //获取对象input file 的图片地址,放进 ...
- 第四章初始CSS3预习笔记
第四章 初始CSS3预习笔记 一: 1: 什么是CSS? 全称是层叠样式表;/通常又称为风格样式表,.他是用来进行网页风格设计的; 2:CSS的优势: 1>内容以表现分离,即使用u前面学习的HT ...
- Gradle、Gradle Wrapper与Android Plugin for Gradle
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...
- 使用Q进行同步的Promises操作
如何通过使用Q来并发执行多个promises呢? Q(Q(1), Q(2), Q(3)) .then(function (one, two, three) { console.log(one); co ...
- Docker三十分钟快速入门(上)
一.背景 最近,Docker技术真是一片火热,它的出现也弥补了虚拟机资源消耗过高的问题,直接让虚拟化技术有了质的飞跃.那么本文我们来聊一聊Docker,和大家一起认识Docker,简单入门Dock ...
- IOS10.3上传照片只能拍照不能选择解决办法
升级IOS10.3正式版以后可能会出现上传文件的控件只能拍照而不能选择现有图片的问题. 正好被我们碰到了,于是找了找解决思路,发现如下解决思路: 原代码为: <input type=" ...
- WPF自定义Window样式(2)
1. 引言 在上一篇中,介绍了如何建立自定义窗体.接下来,我们需要考虑将该自定义窗体基类放到类库中去,只有放到类库中,我们才能在其他地方去方便的引用该基类. 2. 创建类库 接上一篇的项目,先添加一个 ...
- C# ASP.NET 转换为int型的方法 很实用
很多新手在搞c#或者.net开发的时候总会碰到一些小问题,如何知道字符能不能为int型 在这里我写了一个小的函数仅供大家参考: /// <summary> /// 判断是不是int型 / ...
- LeetCode第[16]题(Java):3Sum Closest 标签:Array
题目难度:Medium 题目: Given an array S of n integers, find three integers in S such that the sum is closes ...