使用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. mobx 入门

    observable(可观察的数据) 数组 import { observable, isArrayLike } from 'mobx' const arr = observable(['a', 'b ...

  2. Java-栈的学习(字符串的反转)

    StackX类 public class StackX{ private int maxSize; private char StackArray[]; private int top; public ...

  3. ActivityThread

    /** * This manages the execution of the main thread in an * application process, scheduling and exec ...

  4. 自己定义控件-DragButton

    版权声明:本文为博主原创文章.欢迎转载,转载请注明博主和原文链接. https://blog.csdn.net/u014077888/article/details/28097273 一.描写叙述 可 ...

  5. HDFS的namenode从单节点扩展为HA需要注意的问题

    扩展为HA需要注意的问题 原Namenode称为namenode1,新增的Namenode称为namenode2. 从namenode单节点扩展为HA模式官网上有详细的教程,下面是扩展过程中疏忽的地方 ...

  6. Java中关于CountDownLatch的使用

    CyclicBarrier工具类主要是控制多个线程的一起执行,演示程序: import java.util.Random; import java.util.concurrent.CountDownL ...

  7. HDU - 4336 (容斥)

    题意:给你n个奖,每个机会只能中一个奖,中奖的概率分别是{p1,p2,p3......pn}:并且这些奖是两两没有交集.(pi*pj=0)问,需要多少次才能把所有奖都中完的期望值. 先来分析:中所有奖 ...

  8. windows下elasticsearch6.X安装IK分词器

    文章来源:https://www.cnblogs.com/hts-technology/category/1167823.html (一)到官网下载https://github.com/medcl/e ...

  9. DataX的使用

    简介 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.HDFS.Hive.OceanBase.HBase.OTS.ODPS 等各种异构数据源之间高效 ...

  10. 史上最全脉搏心率传感器PulseSensor资料(电路图+中文说明书+最全源代码)

    准确度说明: 1 输入引脚一定要接在模拟输入口上 ESP-D1  只有一个模拟输入口  A0  0-3.3V  心跳不要接在5v上,否则电压不准  ESP-D1开发板有一个5V和一个3.3v 普通ar ...