I want to extend the Identity Users table by adding more profile information. I also want to remove some fields like Surname. Finally, I want to collect the new profile fields in a new tab in the profile editor window.
9 Answer(s)
-
0
- Extend
AbpUsers(add new profile fields)- Define the extra properties in your
*.Domain.Sharedmodule extension configurator:
- Define the extra properties in your
// YourProjectNameModuleExtensionConfigurator.cs (Domain.Shared) using Volo.Abp.ObjectExtending; public static class YourProjectNameModuleExtensionConfigurator { private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); public static void Configure() { OneTimeRunner.Run(() => { ObjectExtensionManager.Instance.Modules().ConfigureIdentity(identity => { identity.ConfigureUser(user => { user.AddOrUpdateProperty<string>("MiddleName"); user.AddOrUpdateProperty<string>("MyCustomField1"); // add as many as you need (with attributes if you want) }); }); }); } }- Map them to real columns on
AbpUsersin your EF Core project (so SQL Server has physical columns):
// YourProjectNameEfCoreEntityExtensionMappings.cs (EntityFrameworkCore project) using Volo.Abp.Identity; using Volo.Abp.ObjectExtending; using Volo.Abp.Threading; public static class YourProjectNameEfCoreEntityExtensionMappings { private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); public static void Configure() { OneTimeRunner.Run(() => { ObjectExtensionManager.Instance .MapEfCoreProperty<IdentityUser, string>("MiddleName") .MapEfCoreProperty<IdentityUser, string>("MyCustomField1"); }); } }- Create and apply the migration (then run
DbMigrator) so the new columns are created in SQL Server.
Remove/hide built-in fields like
Surname- ABP’s
IdentityUserhas built-in fields (likeSurname). Removing the property from the entity is not supported (it’s part of the module contract), but you can:- Stop collecting it in UI (hide/remove it from forms).
- Optionally ignore it in your business rules (leave it empty).
- For the My Profile UI specifically, you can remove the default Personal Info tab and replace it with your own (next section), so you don’t show
Surnameat all.
- ABP’s
Collect new fields in a new tab in “My Profile” (MVC)
- Add a contributor that adds a new tab (group) and optionally removes the built-in Personal Info tab:
using System.Threading.Tasks; using Volo.Abp.Account.Public.Web.ProfileManagement; using Volo.Abp.DependencyInjection; public class MyProfileManagementPageContributor : IProfileManagementPageContributor, ITransientDependency { public Task ConfigureAsync(ProfileManagementPageCreationContext context) { // Optional: remove the built-in personal info group (so you fully replace it) context.Groups.RemoveAll(x => x.Id == "Volo-Abp-Account-PersonalInfo"); // Add your custom tab context.Groups.Add( new ProfileManagementPageGroup( "my-custom-profile", "My Profile (Custom)", typeof(MyCustomProfileManagementGroupViewComponent) ) ); return Task.CompletedTask; } }- Implement the ViewComponent and its view (your form). You can call
IProfileAppService.GetAsync()to getProfileDtoand useExtraPropertiesfor your added fields.
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Volo.Abp.Account; using Volo.Abp.AspNetCore.Mvc; public class MyCustomProfileManagementGroupViewComponent : AbpViewComponent { private readonly IProfileAppService _profileAppService; public MyCustomProfileManagementGroupViewComponent(IProfileAppService profileAppService) { _profileAppService = profileAppService; } public virtual async Task<IViewComponentResult> InvokeAsync() { var profile = await _profileAppService.GetAsync(); return View("~/Pages/Account/Components/MyCustomProfile/Default.cshtml", profile); } }- Register the contributor:
using Volo.Abp.Account.Public.Web.ProfileManagement; using Volo.Abp.Modularity; [DependsOn(/* your web module deps */)] public class YourProjectNameWebModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { Configure<ProfileManagementPageOptions>(options => { options.Contributors.Add(new MyProfileManagementPageContributor()); }); } }- Important for saving extra fields from “My Profile” (so
UpdateProfileDto.ExtraPropertiesis actually applied): Add this mapping (commonly done in your AuthServer or HttpApi.Host module in tiered solutions):
using Volo.Abp.Identity; using Volo.Abp.ObjectExtending; using Volo.Abp.Threading; public class YourProjectNameAuthServerModule : AbpModule { private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); public override void PostConfigureServices(ServiceConfigurationContext context) { OneTimeRunner.Run(() => { ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi( IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.User, getApiTypes: new[] { typeof(ProfileDto) }, updateApiTypes: new[] { typeof(UpdateProfileDto) } ); }); } }Then in your custom tab’s JS/form post, send: - normal fields (`Name`, `UserName`, etc.) - `ExtraProperties` with your new fields (e.g., `MiddleName`)Sources:
- https://abp.io/docs/latest/Customizing-Application-Modules-Extending-Entities
- https://abp.io/community/articles/rixchoha
- https://abp.io/support/questions/3517
- https://abp.io/docs/latest/framework/architecture/modularity/basics
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - Extend
-
0
- In your custom tab, post normal fields by naming inputs exactly like
UpdateProfileDtoproperties (UserName,Name,Surname,Email,PhoneNumber, …), then add your custom fields underExtraPropertiesand callvolo.abp.account.profile.update(...).
1) Razor/CSHTML (custom tab view)
Bind normal fields to
ProfileDto, and render custom fields fromExtraProperties:@using Volo.Abp.Data @model Volo.Abp.Account.ProfileDto <form id="MyPersonalSettingsForm"> <abp-input asp-for="UserName" /> <abp-input asp-for="Name" /> <abp-input asp-for="Surname" /> <abp-input asp-for="Email" /> <abp-input asp-for="PhoneNumber" /> <div class="mb-3"> <label class="form-label" for="MiddleName">Middle name</label> <input id="MiddleName" class="form-control" type="text" value="@(Model.GetProperty<string>("MiddleName"))" /> </div> <abp-button type="submit" button-type="Primary" text="Save" /> </form>2) JavaScript (send normal fields +
ExtraProperties)(function ($) { $(function () { var _profileService = volo.abp.account.profile; $("#MyPersonalSettingsForm").submit(function (e) { e.preventDefault(); if (!$("#MyPersonalSettingsForm").valid()) { return false; } // Collect normal fields from form inputs (UserName, Name, Surname, Email, PhoneNumber...) var input = $("#MyPersonalSettingsForm").serializeFormToObject(); // Add custom fields into ExtraProperties input.ExtraProperties = { MiddleName: $("#MiddleName").val() }; _profileService.update(input).then(function () { abp.notify.success("Saved"); }); }); }); })(jQuery);3) Required server-side mapping for saving
ExtraPropertiesIn a tiered solution, add (once) in your AuthServer (or HttpApi.Host, wherever
ProfileAppServiceruns) module:ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi( IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.User, getApiTypes: new[] { typeof(ProfileDto) }, updateApiTypes: new[] { typeof(UpdateProfileDto) } );Otherwise
UpdateProfileDto.ExtraPropertiesreaches the API but won’t be applied to the user entity.- https://abp.io/support/questions/3517
- https://abp.io/docs/10.2/framework/fundamentals/object-extensions
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - In your custom tab, post normal fields by naming inputs exactly like
-
0
- You can store your custom “extended” user properties in physical columns on
AbpUsersand still post them from your custom tab, but the post payload will still go throughUpdateProfileDto, whose extensibility mechanism isExtraProperties.
The key point is: Map the extension property to an EF Core column (so it’s stored physically), then send it inExtraProperties(so the Profile API can carry it). ABP will persist it into the mapped column.
1) Map the extension property to a physical column (EF Core)
In your
EntityFrameworkCoreproject, in*EfCoreEntityExtensionMappings.Configure():ObjectExtensionManager.Instance .MapEfCoreProperty<IdentityUser, string>( "MiddleName", (entityBuilder, propertyBuilder) => { propertyBuilder.HasMaxLength(64); propertyBuilder.HasDefaultValue(""); } );Create/apply migration => a real
MiddleNamecolumn is created on AbpUsers.2) Ensure the Profile API applies extension properties on update
In your AuthServer (or whichever host contains the
ProfileAppServicein your tiered solution), run:ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi( IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.User, getApiTypes: new[] { typeof(ProfileDto) }, updateApiTypes: new[] { typeof(UpdateProfileDto) } );This is required so
UpdateProfileDto.ExtraPropertiesis mapped onto the user entity during profile updates (and therefore persisted to your physical column mapping).3) JS/form post from your custom tab
Even though storage is a physical column, you still post like this (because the contract is
UpdateProfileDto):var input = $("#MyPersonalSettingsForm").serializeFormToObject(); input.ExtraProperties = input.ExtraProperties || {}; input.ExtraProperties.MiddleName = $("#MiddleName").val(); volo.abp.account.profile.update(input);After step (1) + (2), ABP will save
MiddleNameinto theAbpUsers.MiddleNamecolumn (not JSON), because you mapped it withMapEfCoreProperty.Links:
- https://abp.io/community/articles/nsyhrtna
- https://abp.io/docs/10.2/framework/fundamentals/object-extensions
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - You can store your custom “extended” user properties in physical columns on
-
0
Hi,
The AI bot's answer covers the right approach. Here are the key documentation pages you can refer to for more details:
- Module Entity Extensions - This is the main guide for extending module entities with extra properties, UI visibility, validation, and database mapping.
- Object Extensions - Covers the lower-level
ObjectExtensionManager,MapEfCoreProperty, and how extra properties work under the hood. - Customizing Application Modules: Extending Entities - Different strategies for extending entities (extra properties, EF Core mapping, creating new entities, etc.) and when to use each one.
- Customizing Application Modules: Overriding Services - If you need to override built-in services like
ProfileAppServicefor more advanced customization.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)