使用ABPzero的朋友们都知道,User表中有Name和Surname两个字段,这两个字段对于国内的用户来说相当的不友好。

以及我们的一些系统中是不会涉及到EmailAddress字段。也就是说不会使用邮箱来进行注册的,那么我们怎么解决了。

首先感谢群友https://github.com/maliming 提供的思路。

  • 在abpzero中的AbpUser实体中Name和Surname、EmailAddress都是为必填。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Configuration;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Extensions; namespace Abp.Authorization.Users
{
/// <summary>
/// Represents a user.
/// </summary>
public abstract class AbpUser<TUser> : AbpUserBase, IFullAudited<TUser>, IPassivable
where TUser : AbpUser<TUser>
{
/// <summary>
/// UserName of the admin.
/// admin can not be deleted and UserName of the admin can not be changed.
/// </summary>
public const string AdminUserName = "admin"; /// <summary>
/// Maximum length of the <see cref="Name"/> property.
/// </summary>
public const int MaxNameLength = 32; /// <summary>
/// Maximum length of the <see cref="Surname"/> property.
/// </summary>
public const int MaxSurnameLength = 32; /// <summary>
/// Maximum length of the <see cref="Password"/> property.
/// </summary>
public const int MaxPasswordLength = 128; /// <summary>
/// Maximum length of the <see cref="Password"/> without hashed.
/// </summary>
public const int MaxPlainPasswordLength = 32; /// <summary>
/// Maximum length of the <see cref="EmailConfirmationCode"/> property.
/// </summary>
public const int MaxEmailConfirmationCodeLength = 328; /// <summary>
/// Maximum length of the <see cref="PasswordResetCode"/> property.
/// </summary>
public const int MaxPasswordResetCodeLength = 328; /// <summary>
/// Maximum length of the <see cref="AuthenticationSource"/> property.
/// </summary>
public const int MaxAuthenticationSourceLength = 64; /// <summary>
/// Authorization source name.
/// It's set to external authentication source name if created by an external source.
/// Default: null.
/// </summary>
[MaxLength(MaxAuthenticationSourceLength)]
public virtual string AuthenticationSource { get; set; } /// <summary>
/// Name of the user.
/// </summary>
[Required]
[StringLength(MaxNameLength)]
public virtual string Name { get; set; } /// <summary>
/// Surname of the user.
/// </summary>
[Required]
[StringLength(MaxSurnameLength)]
public virtual string Surname { get; set; } /// <summary>
/// Return full name (Name Surname )
/// </summary>
[NotMapped]
public virtual string FullName { get { return this.Name + " " + this.Surname; } } /// <summary>
/// Password of the user.
/// </summary>
[Required]
[StringLength(MaxPasswordLength)]
public virtual string Password { get; set; } /// <summary>
/// Is the <see cref="AbpUserBase.EmailAddress"/> confirmed.
/// </summary>
public virtual bool IsEmailConfirmed { get; set; } /// <summary>
/// Confirmation code for email.
/// </summary>
[StringLength(MaxEmailConfirmationCodeLength)]
public virtual string EmailConfirmationCode { get; set; } /// <summary>
/// Reset code for password.
/// It's not valid if it's null.
/// It's for one usage and must be set to null after reset.
/// </summary>
[StringLength(MaxPasswordResetCodeLength)]
public virtual string PasswordResetCode { get; set; } /// <summary>
/// Lockout end date.
/// </summary>
public virtual DateTime? LockoutEndDateUtc { get; set; } /// <summary>
/// Gets or sets the access failed count.
/// </summary>
public virtual int AccessFailedCount { get; set; } /// <summary>
/// Gets or sets the lockout enabled.
/// </summary>
public virtual bool IsLockoutEnabled { get; set; } /// <summary>
/// Gets or sets the phone number.
/// </summary>
public virtual string PhoneNumber {get; set; } /// <summary>
/// Is the <see cref="AbpUser{TUser}.PhoneNumber"/> confirmed.
/// </summary>
public virtual bool IsPhoneNumberConfirmed { get; set; } /// <summary>
/// Gets or sets the security stamp.
/// </summary>
public virtual string SecurityStamp { get; set; } /// <summary>
/// Is two factor auth enabled.
/// </summary>
public virtual bool IsTwoFactorEnabled { get; set; } /// <summary>
/// Is this user active?
/// If as user is not active, he/she can not use the application.
/// </summary>
public virtual bool IsActive { get; set; } /// <summary>
/// Login definitions for this user.
/// </summary>
[ForeignKey("UserId")]
public virtual ICollection<UserLogin> Logins { get; set; } /// <summary>
/// Roles of this user.
/// </summary>
[ForeignKey("UserId")]
public virtual ICollection<UserRole> Roles { get; set; } /// <summary>
/// Claims of this user.
/// </summary>
[ForeignKey("UserId")]
public virtual ICollection<UserClaim> Claims { get; set; } /// <summary>
/// Permission definitions for this user.
/// </summary>
[ForeignKey("UserId")]
public virtual ICollection<UserPermissionSetting> Permissions { get; set; } /// <summary>
/// Settings for this user.
/// </summary>
[ForeignKey("UserId")]
public virtual ICollection<Setting> Settings { get; set; } public virtual TUser DeleterUser { get; set; } public virtual TUser CreatorUser { get; set; } public virtual TUser LastModifierUser { get; set; } protected AbpUser()
{
IsActive = true;
IsLockoutEnabled = true;
SecurityStamp = SequentialGuidGenerator.Instance.Create().ToString();
} public virtual void SetNewPasswordResetCode()
{
PasswordResetCode = Guid.NewGuid().ToString("N").Truncate(MaxPasswordResetCodeLength);
} public virtual void SetNewEmailConfirmationCode()
{
EmailConfirmationCode = Guid.NewGuid().ToString("N").Truncate(MaxEmailConfirmationCodeLength);
} public override string ToString()
{
return string.Format("[User {0}] {1}", Id, UserName);
}
}
}

以上为ABPZERO源代码中的字段,我们怎么修改呢。

  • 修改User实体信息。

    打开我们项目中的User.cs实体。
public class User : AbpUser<User>
{
public const string DefaultPassword = "123qwe"; public static string CreateRandomPassword()
{
return Guid.NewGuid().ToString("N").Truncate(16);
} private new string Name { get; set; } private new string Surname { get; set; } [Required(AllowEmptyStrings = true)]
public override string EmailAddress { get; set; } public static User CreateTenantAdminUser(int tenantId, string emailAddress, string password)
{
return new User
{
TenantId = tenantId,
UserName = AdminUserName,
Name = AdminUserName,
Surname = AdminUserName,
EmailAddress = emailAddress,
Password = new PasswordHasher().HashPassword(password)
};
}
}

可以看到我将Name和SurName字段设置为private,这样设置之后,就有了值对象的感觉,EF在做实体验证的时候就不会对private的属性字段进行验证。

而Emailaddress因为涉及了很多的业务情况,我们不能将它设置为私有访问。

  • 修改DbContext

我们打开'CMSDbContext.cs',添加方法

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); modelBuilder.Entity<User>().Ignore(a => a.Name);
modelBuilder.Entity<User>().Ignore(a => a.Surname); modelBuilder.Entity<User>().Property(a => a.EmailAddress).IsOptional();
// modelBuilder.Entity<User>().a => a.Name); }

覆盖方法‘OnModelCreating’,然后将Name和SurName设置为忽略。

然后将EmailAddress设置为可空。

  • 执行迁移

    然后执行迁移文件命令:"add-migration Remove_Name_SurName".

    然后再执行"update-database",生成的数据库中就不会有“Name”和“Surname”。
  • 到目前为止,Name和SurName就不影响功能使用和开发了。

EmailAddress实体字段修改

   CheckErrors(await _userManager.CreateAsync(user));

在userManager领域服务中的CreateAsync提供的方法中,检查了EmailAddress 所以我们要重写方法。

修改后的'UserManager.cs'

  public class UserManager : AbpUserManager<Role, User>
{
private readonly IUnitOfWorkManager _unitOfWorkManager; public UserManager(
UserStore userStore,
RoleManager roleManager,
IPermissionManager permissionManager,
IUnitOfWorkManager unitOfWorkManager,
ICacheManager cacheManager,
IRepository<OrganizationUnit, long> organizationUnitRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IOrganizationUnitSettings organizationUnitSettings,
ILocalizationManager localizationManager,
ISettingManager settingManager,
IdentityEmailMessageService emailService,
IUserTokenProviderAccessor userTokenProviderAccessor, IUnitOfWorkManager unitOfWorkManager1)
: base(
userStore,
roleManager,
permissionManager,
unitOfWorkManager,
cacheManager,
organizationUnitRepository,
userOrganizationUnitRepository,
organizationUnitSettings,
localizationManager,
emailService,
settingManager,
userTokenProviderAccessor)
{
_unitOfWorkManager = unitOfWorkManager1;
} public override async Task<IdentityResult> CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId, string userName, string emailAddress)
{
var user = (await FindByNameAsync(userName));
if (user != null && user.Id != expectedUserId)
{
return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateName"), userName));
} return IdentityResult.Success;
} private string L(string name)
{
return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name);
} public override async Task<IdentityResult> CreateAsync(User user)
{
var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress);
if (!result.Succeeded)
{
return result;
} user.EmailAddress = string.Empty; var tenantId = GetCurrentTenantId();
if (tenantId.HasValue && !user.TenantId.HasValue)
{
user.TenantId = tenantId.Value;
} try
{
return await base.CreateAsync(user);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
} } private int? GetCurrentTenantId()
{
if (_unitOfWorkManager.Current != null)
{
return _unitOfWorkManager.Current.GetTenantId();
} return AbpSession.TenantId;
}
}

截止以上我们的功能EmailAddress功能就算正常了。

以下为旧文,大家可以自己对比观察。

使用ABPzero的朋友们都知道,User表中有Name和Surname两个字段,这两个字段对于国内的用户来说相当的不友好。

我们在尝试了很多的方法之后,发现无法完美将他们干掉。

所以尝试使用了一个比较不友好加流氓的方式来使用它。

如果你在使用的过程有更加美好的解决方案,可以提供给我们。

以及到https://github.com/aspnetboilerplate/module-zero/issues/337 这里提出方法。

开始流程:

首先到 "CMSDbContext.cs"中添加覆盖方法,找不到的如图所示:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Ignore(a => a.Name);
modelBuilder.Entity<User>().Ignore(a => a.Surname); }

然后执行迁移文件命令:"add-migration Remove_Name_SurName".

然后再执行"update-database",生成的数据库中就不会有“Name”和“Surname”。

但是坑爹的地方就在这,我们在执行Insert(User)方法的时候还是会报错。对于这种情况。我深深的感觉到了无力(感觉身体被Kid掏空)。

没有其他办法,只能暴力解决。在方法中,默认添加Name和Surname的值,只是为了绕过Eentityframework的实体验证。。

如下图所示。

这样绕过之后,发现可以正常的处理信息。

User表中的Name和Surname也不在了。唯一不友好的地方就是坑爹。。

以上算是一个坑爹解决方法。

如果你有更加友好的解决方法。联系我。

ABPZero中的Name和SurName处理,以及EmailAddress解决方案(完美)。的更多相关文章

  1. ABPZero中的Name和SurName处理

    使用ABPzero的朋友们都知道,User表中有Name和Surname两个字段,这两个字段对于国内的用户来说相当的不友好. 我们在尝试了很多的方法之后,发现无法完美将他们干掉. 所以尝试使用了一个比 ...

  2. ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案

    摘要: ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案 在struts2应用中使用ueditor富文本编辑器上传图片或者附件时,即使配置 ...

  3. JSP中pageEncoding和charset区别,中文乱码解决方案(转载)

    转载自:JSP中pageEncoding和charset区别,中文乱码解决方案 JSP指令标签中<%@ page contentType="text/html;charset=GB23 ...

  4. iOS 开发中,关于xxx.xcodeproj 文件冲突的解决方案 (以后谁不会了,直接将连接给他)

    iOS 开发中,关于xxx.xcodeproj 文件冲突的解决方案 (一有冲突要手把手教一遍,太麻烦了,现在总结下,以后谁不会了,连接直接发他). 关于xxx.xcodeproj 文件冲突的话,是比较 ...

  5. MySQL安装过程中对The error code is 2203的解决方案

    MySQL安装过程中对The error code is 2203的解决方案 1.问题描述 Windows系统安装MySQL遇到The error code is 2203.,具体描述如下 The i ...

  6. vue 在有大数据量的 table 中使用弹窗 input 输入数据时卡顿解决方案

    vue 在有大数据量的 table 中使用弹窗 input 输入数据时卡顿解决方案 原因:vue在进行输入时,进行了多次的render刷新渲染操作,导致了input框输入时发生的卡顿现象 解决方法:在 ...

  7. VS·调试过程中某个操作导致调试突然退出之解决方案

    阅文时长 | 0.11分钟 字数统计 | 232字符 主要内容 | 1.引言&背景 2.声明与参考资料 『VS·调试过程中某个操作导致调试突然退出之解决方案』 编写人 | SCscHero 编 ...

  8. 在ABPZERO中,扩展实体的方法。

    内容 介绍 扩展的抽象实体 将新属性添加给用户 添加迁移 在界面上显示地址 在用户编辑/添加功能中添加地址 扩展的非抽象类实体 获得版本的派生实体 添加迁移 在界面上添加价格 在创建/编辑版本功能中加 ...

  9. 在AbpZero中hangfire后台作业的使用——hangfire的调度

    在abpzero框架中,hangfiire通过依赖注入来进行接口的调用 hangfire的事件处理分为以下几种: 1.基于队列的任务处理(Fire-and-forget jobs) var jobId ...

随机推荐

  1. Centos7下搭建SVN服务,本地提交代码自动同步到WEB目录

    1.安装SVN服务[root@bogon ~]# yum -y install subversion 2.查看svnserve安装目录[root@bogon ~]# whereis svnserves ...

  2. Linux文件和目录的粘滞位(sticky bit)

    今天维护系统时发现一个非常诡异的问题:AAA用户和BBB用户同属AAA组,但用AAA用户创建的文件,权限设置为777后,还是不能用BBB用户删除.诡异! 几经周转,发现AAA用户创建文件位置的上层目录 ...

  3. shell脚本之颜色效果显示以及PS1颜色实战

    在bash shell脚本中我们可以使用ASCII颜色来显示文本信息. 格式:\033\[31m hello \033[0m ##m: 左侧#:这个#可以是3或者4,作用不一样. 3:前景色 4:背景 ...

  4. 17秋 软件工程 第六次作业 Beta冲刺 Scrum4

    17秋 软件工程 第六次作业 Beta冲刺 Scrum4 各个成员冲刺期间完成的任务 世强:完成APP用户签到模块.群发短信模块前端界面: 陈翔:恢复Github项目,完成Scrum博客: 树民:和超 ...

  5. 实现strStr()的golang实现

    实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...

  6. Sublime Text 3安装及常用插件安装

    一.Sublime3下载 1.百度搜索Sublime3 download,选择进入下载页面 2.我选择下载Win64位安装程序 二.Sublime3安装 傻瓜式安装,一直点下一步即可. 三.Subli ...

  7. 使用requests模块post payload请求

    import json import requests import datetime postUrl = 'https://sellercentral.amazon.com/fba/profitab ...

  8. esp8266(3) Arduino通过ESP8266连接和获取网站源代码

    http://www.plclive.com/a/tongxinjiekou/2016/0422/374.html 在上一篇8266的基础上,这一篇做个具体的连接网站的例子,供大家参考.上一篇基础篇请 ...

  9. python3 is和==

    '''is 判断左右两端的数据是否是同一个内存地址== 判断左右两端的数据是否一样'''# s1 = "alex"# s2 = "alex"# print(s1 ...

  10. LeetCode算法题详解之两个数组的交集

    题目背景: 这个与我们高中时期学习的交集是一样的,顺便复习一下相关的数学知识有助于更好的理解. 交集的定义: 对于两个集合A和B,定义A和B的交集为C,其中C={x|x属于A且X属于B},记作A∩B. ...