MyApp.HomeServices) and use it to guard your “Home services” UI/API.Example (application service guard):
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Features;
public class HomeServiceAppService : ApplicationService
{
private readonly IFeatureChecker _featureChecker;
public HomeServiceAppService(IFeatureChecker featureChecker)
{
_featureChecker = featureChecker;
}
public async Task DoSomethingAsync()
{
if (!await _featureChecker.IsEnabledAsync("MyApp.HomeServices"))
{
throw new AbpAuthorizationException("Home services is not enabled for this tenant.");
}
// ...
}
}
This approach makes the feature actually unavailable for tenants where it’s disabled (not just “permission disabled”).
That behavior typically happens when the current user does not have the right to grant/revoke those permissions (permission grant/revoke is itself protected). So they can “see” permissions but cannot change them. If you want only host to manage what tenants can use, keep it that way and manage tenant permissions/features from the host side.
Define permissions and use ABP’s multi-tenancy side for permissions (Host, Tenant, Both) and then grant permissions to tenant roles accordingly. This is good for authorization, but it’s not the same as “module enable/disable”.
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.
Volo.Abp.Identity.Pro.Web) renders the admin lists (Users/Roles/ClaimTypes/OpenIddict, etc.) using jQuery DataTables.dom/wrapper HTML/CSS). That’s why your Angular project doesn’t show it: it doesn’t use the Razor/DataTables-based pages.Workaround (recommended, no module source change): override the DataTables dom for the affected pages
dom (or removing one of the duplicated containers).A practical approach is to set a custom dom (single length + filter + table + info + pager). Example:
// wwwroot/js/fix-identity-datatables-pager.js
(function () {
// Hook into ABP's DataTable default options
if (!($.fn && $.fn.dataTable)) {
return;
}
// If ABP (or your page) initializes tables multiple times with different layouts,
// forcing a consistent dom avoids duplicated pagers.
$.extend(true, $.fn.dataTable.defaults, {
// One top row (length + filter), one bottom row (info + pager)
dom:
"<'row'<'col-sm-6'l><'col-sm-6'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>"
});
})();
Then include it (e.g. in your main layout or a bundle) so it’s loaded after jQuery/DataTables/ABP scripts.
If you prefer a “surgical” fix per-page, you can also override the page’s DataTable options where the table is created and set dom there (same idea).
Why this happens in 10.3
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.
ABP Studio currently supports Windows and macOS (Apple Silicon + Intel). There is no verified public information (docs/roadmap/announcement) stating that Linux support is planned or giving an ETA.
If Linux support is important for your team, the official way to request/track it is to contact ABP/Volosoft via the support channels and share your use-case (distro, desktop environment, required features, etc.).
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.
Actionable next step (the only definitive one):
(If you want, you can also point them to the current public claim on the module page about multi-tenancy and ask for clarification/updated docs, but I can’t provide a verified roadmap beyond directing you to the official channel.)
Links used:
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.
BsonDefaults.GuidRepresentationMode was part of older driver APIs. In MongoDB.Driver 3.x (used by ABP 9.2+ / ABP 10), that property is not available, so your compile error is expected.LegacyGuidConvention) so Guid fields (including ABP Entity<Guid>.Id) are read/written using the legacy representation.Use only the convention-based fix (remove BsonDefaults.GuidRepresentationMode entirely) and ensure it runs very early (in your *.MongoDb module PreConfigureServices so it happens before Mongo mappings initialize):
using MongoDB.Bson.Serialization.Conventions;
using Volo.Abp.Modularity;
public class YourProjectMongoDbModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var conventionPack = new ConventionPack { new LegacyGuidConvention() };
ConventionRegistry.Register(
"LegacyGuidConvention",
conventionPack,
_ => true);
}
}
And LegacyGuidConvention should set GuidSerializer(GuidRepresentation.CSharpLegacy) for Guid and Guid? (as in the ABP community article you referenced earlier).
If you had already run the app (or tests) without the convention, restart the process after adding this (MongoDB serialization conventions/class maps are effectively “startup-time” decisions).
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.
UuidStandard by default, while your existing documents (created with older driver versions) often contain UuidLegacy. That’s why you see problems specifically when deserializing existing Entity<Guid>.Id values.GuidRepresentation.CSharpLegacy for Guid and Guid?, and register it once at application startup, before any MongoDB class maps/serializers are used.Add this to your *.MongoDb module (e.g. YourProjectMongoDbModule) ConfigureServices:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Conventions;
using Volo.Abp.Modularity;
public class YourProjectMongoDbModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// Important for MongoDB.Driver v3.x+
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
// Register once (avoid duplicate registration on hot-reload/tests)
if (!ConventionRegistry.Lookup("LegacyGuidConvention").Any())
{
var pack = new ConventionPack
{
new LegacyGuidConvention()
};
ConventionRegistry.Register(
"LegacyGuidConvention",
pack,
_ => true
);
}
}
}
And use this convention implementation:
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.Serializers;
using System;
public class LegacyGuidConvention : ConventionBase, IMemberMapConvention
{
public void Apply(BsonMemberMap memberMap)
{
if (memberMap.MemberType == typeof(Guid))
{
memberMap.SetSerializer(new GuidSerializer(GuidRepresentation.CSharpLegacy));
}
else if (memberMap.MemberType == typeof(Guid?))
{
var guidSerializer = new GuidSerializer(GuidRepresentation.CSharpLegacy);
memberMap.SetSerializer(new NullableSerializer<Guid>(guidSerializer));
}
}
}
This makes ABP’s Id (and any other Guid fields) continue to be stored/read in the old (CSharpLegacy) format, so existing documents deserialize correctly and new inserts remain compatible with your current database.
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.
RMG020 warnings come from Mapperly’s source generator (used by ABP v10+) and mean: “your mapping exists, but some source members are not mapped to the target type”.Department likely inherits audited / soft-delete / multi-tenant fields (TenantId, IsDeleted, CreationTime, etc.), while DepartmentExcelDto intentionally doesn’t contain them—so Mapperly warns for each such mapping.To avoid thousands of warnings, you have these ABP-friendly options:
using Riok.Mapperly.Abstractions;
using Volo.Abp.Mapperly;
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class DemoApplicationMappers
{
// your mapping methods
}
With RequiredMappingStrategy.Target, Mapperly will ensure all destination members are mapped, but it won’t warn just because the source has extra properties (like audit fields).
using Riok.Mapperly.Abstractions;
[Mapper]
public partial class DepartmentExcelMapper
{
[MapperIgnoreSource(nameof(Department.TenantId))]
[MapperIgnoreSource(nameof(Department.ParentDepartmentId))]
[MapperIgnoreSource(nameof(Department.IsDeleted))]
[MapperIgnoreSource(nameof(Department.DeleterId))]
[MapperIgnoreSource(nameof(Department.DeletionTime))]
[MapperIgnoreSource(nameof(Department.LastModificationTime))]
[MapperIgnoreSource(nameof(Department.LastModifierId))]
[MapperIgnoreSource(nameof(Department.CreationTime))]
[MapperIgnoreSource(nameof(Department.CreatorId))]
public partial DepartmentExcelDto Map(Department source);
}
Use this when you want to keep “warn on unmapped source” for most mappings, but selectively suppress noise for DTOs that intentionally exclude infrastructure fields.
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.
Operation Rate Limiting is a Pro (commercial) module, so you won’t find its full implementation source code in the public abpframework/abp GitHub repository. That GitHub page you referenced is only the documentation for the module, not its source code:
https://github.com/abpframework/abp/blob/dev/docs/en/modules/operation-rate-limiting.md
How to get the source code (the supported way):
If you still don’t see it in the Pro source bundle: this typically means one of these is true:
If you need your entitlement checked or enabled for that specific module/source package, please contact sales/support here:
https://abp.io/contact
(Reference doc page for the module: https://abp.io/docs/latest/modules/operation-rate-limiting)
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.
ReplaceableComponentsService is still a supported approach. The replacement mechanism itself did not get removed; the key thing is using the correct replaceable key and providing a component that matches LeptonX’s toolbar/container expectations.UserMenuService” approach didn’t reflect in the LeptonX profile dropdown is that LeptonX Pro’s profile dropdown is driven by LeptonX’s own user/profile context menu (action groups), not necessarily the same render path as UserMenuService items. In practice, the stable customization point is to replace the toolbar (or current user area) and render your own context menu, exactly like the workaround you described.ToolbarComponent) and adjust what’s shown / behavior.ToolbarContainerComponent) that renders the profile context menu the way you want.import { ReplaceableComponentsService } from '@abp/ng.core';
import { eThemeLeptonXComponents } from '@volosoft/abp.ng.theme.lepton-x';
import { MyToolbarContainerComponent } from './my-toolbar-container.component';
constructor() {
inject(ReplaceableComponentsService).add({
key: eThemeLeptonXComponents.Toolbar,
component: MyToolbarContainerComponent,
});
}
This is the same pattern Volosoft has recommended in support answers for LeptonX Angular customization (toolbar replacement).
ABP supports pulling the theme package with source code into your Angular solution:
abp add-package @volosoft/abp.ng.theme.lepton-x --with-source-code
Then you can customize/override theme assets/components in your project while keeping the rest of ABP intact.
eThemeLeptonXComponents.Toolbar replacement and custom toolbar/container components)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.