Please contact us at https://abp.io/contact.
(Your questions are specifically about ABP Commercial licensing terms—project limits, deployment rights, renewal/downgrade implications, and the runtime behavior/implications of AbpLicenseCode—which are license/commercial topics that must be confirmed by Volosoft against your subscription.)
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.
Do not try to keep Angular 17 with ABP 10.6. ABP v10.6 Angular UI stack is upgraded to Angular 22.0.x, so the Angular frontend must be upgraded accordingly (or you must stay on an older ABP version on the backend too). This version coupling is the main reason you see “a lot of issues” when jumping from ABP 8.3 to ABP 10.6.
Upgrade path (recommended, deterministic):
package.json versions (Angular + @abp/* + @volo/*)app.config.ts / routing / provider setup@abp/* and @volo/* packages to 10.6.* (keep them aligned; don’t mix major versions).@angular/* packages to the same minor/patch line).projects/*, re-apply your custom changes on top of the new 10.6 theme sources (otherwise DI tokens/components can mismatch, producing runtime errors similar to the ones seen in support tickets when package sources are out-of-sync).Mandatory docs to follow while upgrading (in order):
What Angular version should you target?
With ABP 10.6, target Angular 22.0.x (per ABP 10.6 release info). Any attempt to “stay at Angular 17” while using ABP 10.6 packages will typically fail due to peer deps and runtime incompatibilities.
If your upgrade reports include specific errors (build errors, DI token/provider issues, LeptonX issues, proxy generation issues), the fastest reliable method is still:
(Your two attached markdown reports are not accessible from here via the provided links, so I can’t comment line-by-line on them. The steps above are the verified ABP version alignment requirement and the safest upgrade procedure for large jumps.)
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.
Server-side filtering on ExtraProperties (without MapEfCoreProperty): No, not in a supported/official way today. In ABP’s EF Core integration, ExtraProperties is stored via a value conversion (JSON string <-> ExtraPropertyDictionary). Because of that, EF Core cannot translate arbitrary predicates over dictionary contents to SQL, so you effectively can’t get provider-side translation (e.g., JSON_VALUE, ->>, etc.) unless you promote the property to a real mapped column using ObjectExtensionManager.MapEfCoreProperty(...).
Mapping ExtraProperties to provider-native JSON column types (json / jsonb): No supported ABP extension point is documented to change the store type of ExtraProperties from its current string-based persistence to provider-native JSON types. ABP’s entity extension system is designed around:
ExtraProperties) andMapEfCoreProperty.Overriding the mapping yourself (HasColumnType("json") + custom converter) — is it “supported”?: There is no verified ABP guidance stating that changing the underlying column type / conversion strategy of ExtraProperties is supported or upgrade-safe. Since ABP modules and conventions assume ExtraProperties is serialized JSON stored in a regular column, overriding it may work technically for your EF Core provider, but it is not something ABP commits to as a stable customization surface (so it can break with framework/provider upgrades).
Runtime-only property names (user-defined after deployment): ABP’s intended path is not “query these runtime keys inside ExtraProperties in SQL”. The documented/established mechanism for queryability is design-time mapping with MapEfCoreProperty, which inherently can’t cover unknown-at-deploy keys. For your requirement (tenant-specific runtime schema + indexed JSON path querying), ExtraProperties is not a good fit as the primary query surface.
Recommendation (given your performance findings and requirements):
ExtraProperties for what it’s best at: extensibility, UI/form metadata, occasional values, non-query-critical dynamic data.json + JSON index (or PostgreSQL jsonb + GIN),If you want, you can still mirror a small subset of “hot” attributes into promoted ABP extension columns (via MapEfCoreProperty) for the cases where keys become stable and worth first-class columns, while keeping the long tail in your JSON attribute store.
Link 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.
Fix the empty “Type” dropdown
department, employee_id, etc.).Prevent saving empty claims (mandatory validation)
[Required]) for Type and Value (and/or validate manually and throw).If you only configure claim types (first part), you’ll also naturally reduce the chance of empty “Type” because users can pick a real type.
Quiet reference:
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.
Your analysis is correct: subscribing to a scoped PageLayout using anonymous async lambdas (effectively async void handlers for these events) and never unsubscribing can keep dead components alive and can also dispatch StateHasChanged() after the renderer/component scope is already disposed. In a Blazor Web App (InteractiveAuto), that race window is easier to hit, and an exception escaping an async void event handler can indeed become process-terminating.
Until there is an upstream fix in Volo.Abp.AspNetCore.Components.Web.LeptonXTheme, the safest application-level mitigation is exactly what you already did: replace the LeptonX theme components via DI and implement proper unsubscribe on dispose.
Create code-behind only subclasses (so you inherit the original generated markup) and replace the event hookups with named, non-async-void handlers + IDisposable.
using System.Collections.Specialized;
using System.ComponentModel;
using Microsoft.AspNetCore.Components;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
public class MySafeContentToolbar : ContentToolbar, IDisposable
{
private NotifyCollectionChangedEventHandler? _toolbarItemsChanged;
private PropertyChangedEventHandler? _pageLayoutPropertyChanged;
protected override Task OnInitializedAsync()
{
_toolbarItemsChanged = ToolbarItemsChanged;
_pageLayoutPropertyChanged = PageLayoutPropertyChanged;
PageLayout.ToolbarItems.CollectionChanged += _toolbarItemsChanged;
PageLayout.PropertyChanged += _pageLayoutPropertyChanged;
// IMPORTANT: do NOT call base.OnInitializedAsync() (it attaches the anonymous handlers)
return Task.CompletedTask;
}
private void ToolbarItemsChanged(object? sender, NotifyCollectionChangedEventArgs e)
=> _ = InvokeAsync(RenderAsync); // observe on renderer sync context
private void PageLayoutPropertyChanged(object? sender, PropertyChangedEventArgs e)
=> _ = InvokeAsync(StateHasChanged);
public void Dispose()
{
if (_toolbarItemsChanged != null)
{
PageLayout.ToolbarItems.CollectionChanged -= _toolbarItemsChanged;
}
if (_pageLayoutPropertyChanged != null)
{
PageLayout.PropertyChanged -= _pageLayoutPropertyChanged;
}
}
}
using System.Collections.Specialized;
using System.ComponentModel;
using Microsoft.AspNetCore.Components;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
public class MySafeBreadcrumbs : Breadcrumbs, IDisposable
{
private NotifyCollectionChangedEventHandler? _breadcrumbItemsChanged;
private PropertyChangedEventHandler? _pageLayoutPropertyChanged;
protected override Task OnInitializedAsync()
{
_breadcrumbItemsChanged = BreadcrumbItemsChanged;
_pageLayoutPropertyChanged = PageLayoutPropertyChanged;
PageLayout.BreadcrumbItems.CollectionChanged += _breadcrumbItemsChanged;
PageLayout.PropertyChanged += _pageLayoutPropertyChanged;
// IMPORTANT: do NOT call base.OnInitializedAsync()
return Task.CompletedTask;
}
private void BreadcrumbItemsChanged(object? sender, NotifyCollectionChangedEventArgs e)
=> _ = InvokeAsync(StateHasChanged);
private void PageLayoutPropertyChanged(object? sender, PropertyChangedEventArgs e)
=> _ = InvokeAsync(StateHasChanged);
public void Dispose()
{
if (_breadcrumbItemsChanged != null)
{
PageLayout.BreadcrumbItems.CollectionChanged -= _breadcrumbItemsChanged;
}
if (_pageLayoutPropertyChanged != null)
{
PageLayout.PropertyChanged -= _pageLayoutPropertyChanged;
}
}
}
Register replacements (as you noted, for Blazor Web App do it in both Server and .Client modules where the layout can render):
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
context.Services.Replace(ServiceDescriptor.Transient<ContentToolbar, MySafeContentToolbar>());
context.Services.Replace(ServiceDescriptor.Transient<Breadcrumbs, MySafeBreadcrumbs>());
async void propagation → work is scheduled via InvokeAsync(...) and exceptions are observed by the renderer pipeline rather than surfacing as unhandled ThreadPool exceptions.Dispose() ensures dead components stop receiving layout notifications, preventing renders against disposed Autofac scopes.If you want this fixed upstream in the theme package, please report it through the official channel so it can be tracked and patched: https://abp.io/contact
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.
Q1 (intentional? which version?): I can’t verify (with the available indexed docs/code context) when or why ABP Suite changed the naming convention for many-to-many join artifacts (e.g., WorkerCompany → WorkerCompanies, AddCompany → AddToCompanies, AppWorkerCompany → AppWorkerCompanies). The searchable sources I have do not include Suite changelogs or generator code that would let me definitively pinpoint the first version that introduced this behavior.
Q2 (where documented?): I can’t find any verified ABP documentation that calls out a breaking change about regeneration producing different join-entity/method/table names between Suite versions, nor any guidance that warns about EF Core migrations potentially being scaffolded as Drop/Create instead of Rename in this scenario. The only directly relevant official page I can verify is the general “creating many-to-many relationship” document, which describes the feature but does not mention naming stability across Suite versions or regeneration pitfalls.
Q3 (recommended safe path on 10.4.0): The safe, practical approach (to avoid data loss) is:
DropTable / CreateTable for association tables that already have production data.migrationBuilder.RenameTable(...) (and RenameIndex if needed), or implementing a data-move approach (create new table, copy data with SQL, then drop old).DbContext table mappings,I cannot verify any supported Suite option in 10.4.0 that forces the generator to keep the old singular join naming convention for existing entities.
Q4 (should Suite delete obsolete join entity files?): I can’t verify an official guarantee that Suite removes previously generated/now-obsolete join entity classes during regeneration. Based on what you observed (old join entity classes left behind), you should assume it may not clean them up, and you should manually delete/merge them as part of your regeneration review (after confirming nothing references them).
References (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.
Please contact us at https://abp.io/contact.
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.
Fix (recommended approach)
Since your screenshot shows an ABP Commercial LeptonX/Angular-style list, the quickest safe mitigation is a CSS override like:
/* Ensure consistent column widths between header and body */
.audit-logs-table table {
table-layout: fixed;
width: 100%;
}
/* Prevent header text (like "APPLICATION NAME") from changing width calculations */
.audit-logs-table th,
.audit-logs-table td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Apply it by targeting the actual audit logs table wrapper/class in your DOM (inspect the page and replace .audit-logs-table with the real container selector used in your app).
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.
ProcessSignIn pipeline before OpenIddict writes the /connect/token response.session_id to be present in AbpSessions. If the token response is returned before the ambient ABP Unit Of Work is completed, the next request can race and hit IdentitySessionChecker before the AbpSessions insert is visible/committed.OpenIddictCreateIdentitySession handler with a custom handler that:
requiresNew: true)isTransactional: true)CompleteAsync() immediatelyYour sample code matches that pattern; keep it.
.SetOrder(100000) is fine as long as it is effectively executed in the pipeline for ProcessSignIn).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.
ABP Admin Console (React) does not currently auto-render your module/entity extensions (extended/extra properties) on the built-in management screens (Identity Users, Organization Units, Saas Tenants). That’s why:
Required, so saves fail because the Admin Console never posts those valuesRoadmap / “when”
Recommended solutions
Do not use Admin Console for those specific create/edit flows. Build your own pages in your developer-owned React app (the one generated in your solution), where you can fully control the forms and include your extended properties.
extraProperties / your extended fields in the DTO you send.Backend-side mitigation (only if you must keep Admin Console temporarily): make those extended properties non-required or provide defaults
[Required] on the extension definition, or provide a DefaultValue in the extension configuration so the server can accept requests that don’t include those fields.If you want “automatic UI” for extended properties, use a UI that already supports it for those module pages
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.