- ABP Framework version: v5.0.1
- UI type: Angular
- DB provider: EF Core
- Identity Server Separated (Angular): no
Hello! We are trying to hide the username field from the Create and Edit User forms and use the email address for the username instead.
I have successfully removed the username field from the Angular UI and moved the email field to the top like this:
export function removeUserNameContributor(
  propList: FormPropList<IdentityUserDto>
) {
  propList.dropByValue(
    'userName',
    (prop, text) => prop.name === text
  )
  let emailPropIndex = propList.findIndex(p => p.value.name == 'email');
  propList.addHead(propList.get(emailPropIndex).value);
  propList.dropByIndex(emailPropIndex + 1);
}
export const identityEntityCreateFormPropContributors: IdentityCreateFormPropContributors = {
  [eIdentityComponents.Users]: [
    removeUserNameContributor
  ]
}
export const identityEntityEditFormPropContributors: IdentityEditFormPropContributors = {
  [eIdentityComponents.Users]: [
    removeUserNameContributor
  ]
}
{
    path: 'identity',
    loadChildren: () => {
      import('./identity/identity.module').then(m => m.IdentityOverrideModule)
      return import('@volo/abp.ng.identity').then((m) => m.IdentityModule.forLazy({
        createFormPropContributors: identityEntityCreateFormPropContributors,
        editFormPropContributors: identityEntityEditFormPropContributors,
      }))
    }
},
I've also overwritten the CreateAsync method to set the username to the email address:
[Authorize(IdentityPermissions.Users.Create)]
public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{
    var user = new Volo.Abp.Identity.IdentityUser(
        GuidGenerator.Create(),
        input.Email,
        input.Email,
        CurrentTenant.Id
    );
    
    input.MapExtraPropertiesTo(user);
    (await UserManager.CreateAsync(user, input.Password)).CheckErrors();
    
    ...
}
But I am unable to remove the Required attribute from UserName on IdentityUserCreateDto so I get the following error from the form:
In my ...DtoExtensions.cs I have tried:
ObjectExtensionManager.Instance
.AddOrUpdateProperty<string > (
    new[]
    {
        typeof(IdentityUserCreateDto),
    },
    "UserName",
    options => 
    {
        options.Attributes.Clear();
        options.Validators.Clear();
    }
);
and
ObjectExtensionManager.Instance
.AddOrUpdate<IdentityUserCreateDto>(objConfig =>
{
    objConfig.AddOrUpdateProperty<string>("UserName", propertyConfig =>
    {
        propertyConfig.Attributes.Clear();
        propertyConfig.Validators.Clear();
    });
});
and have tried substituting IdentityUserCreateDto with IdentityUserCreateOrUpdateDtoBase but none of these solutions have removed the Required attribute.
Any ideas would be appreciated. Thanks!
2 Answer(s)
- 
    0Hi, The UserNameis required, you need to change the module source code, but it has a lot of work to do.I've also overwritten the CreateAsync method to set the username to the email address: You can use email as a user name in the front end. it should be working. 
- 
    1We're just visually hiding the concept of a UserNameby settingUserName = EmailAddress. That way users are created and sign in using only their email address, with no option for a different username.I ended up solving my issue by adding a hidden userNameproperty with a default value.export function removeUserNameContributor( propList: FormPropList<IdentityUserDto> ) { let previousUserNameProp = propList.get(propList.findIndex(p => p.value.name == 'userName')).value propList.dropByValue( 'userName', (prop, text) => prop.name === text ) propList.addHead({ ...previousUserNameProp, visible: c => false, defaultValue: 'DEFAULTVALUE' } as FormProp<IdentityUserDto>); let emailPropIndex = propList.findIndex(p => p.value.name == 'email'); propList.addHead(propList.get(emailPropIndex).value); propList.dropByIndex(emailPropIndex + 1); }Then in CreateAsyncI ignore the default value in the username and only use the email to create the user.var user = new Volo.Abp.Identity.IdentityUser( GuidGenerator.Create(), input.Email, input.Email, CurrentTenant.Id );Now the username for all users will be their email address. 

 
                                