Open Closed

Extending the Identity User table #10580


User avatar
0
punta created

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.

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

9 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • Extend AbpUsers (add new profile fields)
      1. Define the extra properties in your *.Domain.Shared module extension configurator:
    // 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)
                         });
                     });
                 });
             }
         }
    
    1. Map them to real columns on AbpUsers in 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");
                 });
             }
         }
    
    1. 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 IdentityUser has built-in fields (like Surname). 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 Surname at all.
    • Collect new fields in a new tab in “My Profile” (MVC)

      1. 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;
             }
         }
    
    1. Implement the ViewComponent and its view (your form). You can call IProfileAppService.GetAsync() to get ProfileDto and use ExtraProperties for 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);
             }
         }
    
    1. 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());
                 });
             }
         }
    
    1. Important for saving extra fields from “My Profile” (so UpdateProfileDto.ExtraProperties is 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)
  • User Avatar
    0
    punta created

    How to post the Normal Fields and Custom fields in my custom tab's JS/form?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • In your custom tab, post normal fields by naming inputs exactly like UpdateProfileDto properties (UserName, Name, Surname, Email, PhoneNumber, …), then add your custom fields under ExtraProperties and call volo.abp.account.profile.update(...).

    1) Razor/CSHTML (custom tab view)

    Bind normal fields to ProfileDto, and render custom fields from ExtraProperties:

    @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 ExtraProperties

    In a tiered solution, add (once) in your AuthServer (or HttpApi.Host, wherever ProfileAppService runs) module:

    ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
        IdentityModuleExtensionConsts.ModuleName,
        IdentityModuleExtensionConsts.EntityNames.User,
        getApiTypes: new[] { typeof(ProfileDto) },
        updateApiTypes: new[] { typeof(UpdateProfileDto) }
    );
    

    Otherwise UpdateProfileDto.ExtraProperties reaches 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)
  • User Avatar
    0
    punta created

    I want a physical column to the custom properties. I do not want to store them as extra properties.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • You can store your custom “extended” user properties in physical columns on AbpUsers and still post them from your custom tab, but the post payload will still go through UpdateProfileDto, whose extensibility mechanism is ExtraProperties.
      The key point is: Map the extension property to an EF Core column (so it’s stored physically), then send it in ExtraProperties (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 EntityFrameworkCore project, in *EfCoreEntityExtensionMappings.Configure():

    ObjectExtensionManager.Instance
        .MapEfCoreProperty<IdentityUser, string>(
            "MiddleName",
            (entityBuilder, propertyBuilder) =>
            {
                propertyBuilder.HasMaxLength(64);
                propertyBuilder.HasDefaultValue("");
            }
        );
    

    Create/apply migration => a real MiddleName column is created on AbpUsers.

    2) Ensure the Profile API applies extension properties on update

    In your AuthServer (or whichever host contains the ProfileAppService in your tiered solution), run:

    ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
        IdentityModuleExtensionConsts.ModuleName,
        IdentityModuleExtensionConsts.EntityNames.User,
        getApiTypes: new[] { typeof(ProfileDto) },
        updateApiTypes: new[] { typeof(UpdateProfileDto) }
    );
    

    This is required so UpdateProfileDto.ExtraProperties is 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 MiddleName into the AbpUsers.MiddleName column (not JSON), because you mapped it with MapEfCoreProperty.

    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)
  • User Avatar
    0
    punta created

    That is good. Let me know if Abp Staff have anything to say or recommend.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    The AI bot's answer covers the right approach. Here are the key documentation pages you can refer to for more details:

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    punta created

    That is Great! Thanks a lot!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    : )

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.