abp login is only for ABP CLI (downloading commercial libs, templates, etc.). It does not affect where Yarn/NPM searches for Angular packages.@abp/ng.components is a public NPM package. If Yarn says it can’t find it, you are almost certainly not hitting the public registry (or you have an .npmrc/.yarnrc that overrides the registry).Do the following in your Angular folder:
yarn config set registry https://registry.npmjs.org
npm config set registry https://registry.npmjs.org
rm -rf node_modules yarn.lock package-lock.json
yarn cache clean
yarn install
registry=... or scope registries like @abp:registry=...:
./.npmrc~/.npmrc./.yarnrc / ~/.yarnrcAfter fixing the registry override, yarn install should resolve @abp/ng.components@~9.1.1 normally.
Links:
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.
ConcurrencyStamp is not the reason for the timeout. If the ConcurrencyStamp mismatches, EF Core/ABP would typically result in a concurrency exception (0 rows affected), not a “wait 30s then timeout”. A timeout on that statement means SQL Server is waiting (usually on locks) or the DB is throttling.
Yes, ABP applies Unit of Work to all public Application Service methods, including Get... methods.
Additionally, by default ABP’s UOW transaction behavior is Auto, and HTTP GET requests don’t start a transactional UOW (no explicit DB transaction is created). But the method is still inside a UOW pipeline, and if you do writes (like UpdateAsync) inside a GET, it will still persist changes (via SaveChanges at the end of the UOW / repository autoSave, depending on your code).
About the “EF Core 9 command batching holds locks longer” hint: I can’t verify that claim from ABP/EF sources in the available context here, so I won’t confirm it. What is verifiable and relevant in ABP is: doing UpdateAsync inside a frequently-called GET method can create unexpected write load and lock contention, which does match your symptom.
What to do (definitive ABP guidance):
Remove any update call from GET methods. Split into:
Get... (read-only)Update... (POST/PUT) for writesIf you must keep the GET read-only and want to enforce it, disable UOW or at least make it explicitly non-transactional and don’t call update:
using Volo.Abp.Uow;
[UnitOfWork(IsDisabled = true)]
public virtual async Task<AgentDto> GetAsync(Guid id)
{
// read-only
}
[UnitOfWork(IsTransactional = true)]
public virtual async Task<AgentDto> TouchAndGetAsync(Guid id)
{
// do update + read
}
(verified references)
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.
If you were only restarting ABP Studio without logging out, it can keep using the old Community session state and continue showing this warning (this matches a previously reported case).
For anything license/account related beyond this (e.g., your user not actually assigned to the organization/license on abp.io), please contact the licensing/support team:
https://abp.io/contact
Links you can cross-check:
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.
This looks like a real bug in the AI Management Blazor ChatClientChat component (ABP 10.2.0): when it restores chat history from browser local storage, at least one stored message can have null text/markdown, and the component ends up calling Markdig with a null string (Markdown.ToHtml(null, ...)), which throws System.ArgumentNullException (markdown) and breaks the Blazor circuit.
Your workaround (clearing site data/local storage) is consistent with this: it removes the persisted conversation that contains a null-content message.
There is no verified public fix note/ticket I can point to for ABP 10.2.0 specifically (and I can’t access the commercial source here to confirm whether it’s already patched internally). Practically, until you update to a version where this is fixed, the only deterministic mitigations are:
ConversationId (e.g., include a version suffix like "...-v2" so a new local-storage key is used), orIf you embed the widget yourself (not the built-in playground page), you can also make it resilient by ensuring you never pass a null markdown string into a markdown renderer (i.e., normalize null to "" before rendering). The crash indicates the playground’s own rendering path is missing that guard.
Sources:
ConversationId)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.
AbpUsers and still post them from your custom tab, but the post payload will still go through UpdateProfileDto, whose extensibility mechanism is ExtraProperties.ExtraProperties (so the Profile API can carry it). ABP will persist it into the mapped column.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.
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).
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:
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.
UpdateProfileDto properties (UserName, Name, Surname, Email, PhoneNumber, …), then add your custom fields under ExtraProperties and call volo.abp.account.profile.update(...).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>
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);
ExtraPropertiesIn 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.
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.
AbpUsers (add new profile fields)
*.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)
});
});
});
}
}
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");
});
}
}
DbMigrator) so the new columns are created in SQL Server.Remove/hide built-in fields like Surname
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:
Surname at all.Collect new fields in a new tab in “My Profile” (MVC)
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;
}
}
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);
}
}
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());
});
}
}
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:
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.
In ABP Blazor Server + LeptonX, the FOUC you saw is typically caused by theme-appearance/theme CSS being applied only after the Blazor circuit starts and LeptonX determines the active appearance (light/dark/system). Adding <leptonx-theme-appearance /> fixes the FOUC by applying appearance early, but it can also produce a brief black screen because the page background/appearance is set immediately (often to dark) before the rest of the UI/LeptonX layout finishes rendering under slow networks.
The practical way to avoid both effects is to make the initial HTML render with a stable background + minimal critical CSS, so the browser never shows an unstyled/incorrect theme, and it never shows a black blank page either.
Keep using <leptonx-theme-appearance /> (it’s the correct direction to prevent late theme injection/FOUC).
Add a tiny “critical” inline style (or a very small local CSS loaded before everything else) that:
html, body background to the expected color (or at least a neutral non-black color),Conceptually:
Ensure your LeptonX/ABP global CSS bundle is emitted as early as possible in the host page (_Host.cshtml / layout). In ABP, this is normally done via the theme’s recommended AbpStyles bundle usage (per the LeptonX Blazor doc). If you’ve customized the host markup, revert to the recommended placement so styles are in <head> and not deferred.
If the “black screen” is specifically because the appearance resolves to dark on first load under throttling, set a deterministic default appearance (e.g., Light) instead of “System”, or persist the user preference and apply it immediately. (This prevents an initial “dark background” paint on devices where system preference is dark.)
No verified source available that explicitly states this specific FOUC vs black-screen behavior was fixed in a particular ABP/LeptonX version. The only verified guidance available is the general LeptonX Blazor integration approach and the known “late styles” discussion you already found.
Links (validated):
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.
MyCompany.PublicWeb) to the existing MyCompany.HttpApi.Client project:<!-- MyCompany.PublicWeb.csproj -->
<ItemGroup>
<ProjectReference Include="..\..\src\MyCompany.HttpApi.Client\MyCompany.HttpApi.Client.csproj" />
</ItemGroup>
using Volo.Abp.Modularity;
using MyCompany.HttpApi.Client;
namespace MyCompany.PublicWeb;
[DependsOn(
typeof(MyCompanyHttpApiClientModule) // this is the key
)]
public class MyCompanyPublicWebModule : AbpModule
{
}
// appsettings.json (MyCompany.PublicWeb)
{
"RemoteServices": {
"Default": {
"BaseUrl": "https://localhost:44300"
}
}
}
MyCompany.Application.Contracts) directly in MVC controllers/pages and ABP will call the existing HttpApi.Host through the proxy:public class HomeController : Controller
{
private readonly IMyAppService _myAppService;
public HomeController(IMyAppService myAppService)
{
_myAppService = myAppService;
}
}
Links (verified):
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.
*.Web is an OpenID Connect client of *.AuthServer and calls *.HttpApi.Host with the access token. To add an additional *.Web-like MVC UI that reuses the same AuthServer and HttpApi.Host, you essentially clone the existing Web app pattern: create a new MVC host project/module, set its OIDC client settings to your existing AuthServer, and set its RemoteServices base URL to your existing HttpApi.Host.MyCompany.PublicWeb)MyCompany.PublicWeb (or MyCompany.Web.Public, MyCompany.CorporateWeb, etc.)MyCompany.Web uses (typical references):
MyCompany.HttpApi.Client (so you can call the existing HttpApi.Host)MyCompany.Web-equivalent shared UI module(s) if you have them (optional, depends on how you organized UI code)*.Web module) and depend on ABP MVC UI modules + your app modules.In MyCompany.PublicWeb/appsettings.json, point to the existing AuthServer:
{
"AuthServer": {
"Authority": "https://localhost:44301",
"RequireHttpsMetadata": "false"
},
"App": {
"SelfUrl": "https://localhost:44305"
}
}
Then configure OIDC client settings similarly to your existing *.Web project (same approach, different client id / redirect URL).
In your existing tiered solution’s *.AuthServer, you must register a new client for this new UI (new ClientId, redirect URIs, post-logout redirect URIs), matching the new app’s URL:
https://localhost:44305/signin-oidchttps://localhost:44305/signout-callback-oidc(How you register it depends on your solution’s seeding approach, but it must be done in the AuthServer side.)
In MyCompany.PublicWeb/appsettings.json set the RemoteServices base URL to your existing HttpApi.Host:
{
"RemoteServices": {
"Default": {
"BaseUrl": "https://localhost:44300"
}
}
}
Then ensure the new UI project references/depends on MyCompany.HttpApi.Client so it can use ABP’s generated/typed client proxies to call the existing backend.
If you don’t want LeptonX in the additional UI, use ABP MVC theming/bundling:
Start these 3 apps together:
MyCompany.AuthServerMyCompany.HttpApi.HostMyCompany.PublicWeb (your additional MVC UI)Your new UI will authenticate against the existing AuthServer and call the existing HttpApi.Host, just like the original *.Web.
Sources
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.