(1) Managed Identity support in ABP’s Azure Blob provider (v10.2.0):
In ABP 10.2, the built-in Azure Blob Storage provider is configured via azure.ConnectionString and the documentation describes it as using the connection string (shared key) model. There is no documented option (in ABP 10.2 docs) to pass an Azure.Core.TokenCredential (e.g., DefaultAzureCredential / ManagedIdentityCredential) to the provider.
(2) Recommended extension/customization point:
ABP explicitly documents that AzureBlobProvider is the main class and can be overridden/replaced via dependency injection (replace the AzureBlobProvider class, not IBlobProvider). So the supported approach is:
AzureBlobProvider via DI or create a custom blob provider).BlobServiceClient using new BlobServiceClient(new Uri(accountUrl), new DefaultAzureCredential()) (or ManagedIdentityCredential) and implement required blob operations.Practically, the most “ABP-aligned” options are:
AzureBlobProvider via DI (recommended if you want to keep container.UseAzure(...) configuration style and just change authentication/initialization internals).ProviderType = typeof(YourProvider) (recommended if you want a clean separation and your own strongly-typed provider configuration options).(3) Roadmap plans:
No verified source available for ABP’s roadmap regarding “Azure SDK credential-based authentication for Azure Storage” (Managed Identity / TokenCredential) in the built-in provider.
(4) Samples / best practices published by ABP:
No verified official ABP sample/documentation demonstrating Azure Blob Storage integration using Managed Identity. The available docs and community articles primarily show connection-string based configuration.
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.
Domain / Application / EntityFrameworkCore / HttpApi / Application.Contracts / tests, you should create each microservice as an ABP module solution (microservice-first module design) and then host it with a small HttpApi.Host (or similar) project.
*.HttpApi (and usually *.EntityFrameworkCore) and configures the database connection / migrations.For the requested support call: ABP/Volosoft scheduling and non-technical/support logistics are handled via the contact channel:
Links you can follow for the official guidance and an example:
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 and include:
License/organization membership changes must be handled by the ABP team from the backend.
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.
AssignedUserId -> UserName in your custom list DTO is the correct approach for a microservice solution.That said, in microservices you should prefer calling Identity’s Integration Service (if available in your version/package set) rather than the full “UI/admin” Identity app service endpoints, because integration services are designed specifically for service-to-service scenarios.
Keep AssignedUserId as Guid in WorkItem (no EF navigation to IdentityUser).
In WorkItemsAppService.Extended.cs, implement GetListWithUsernameAsync like:
AssignedUserIdsAssignedUserName on your DTOsEnsure your microservice can forward the current user’s access token to the Identity service when doing remote calls. In ABP microservices this is handled by the Volo.Abp.Http.Client.IdentityModel integration (commonly used by microservice hosts) so the outgoing request contains the Authorization header.
Volo.Abp.Identity.Pro.HttpApi.Client specifically depends on what your solution uses (Pro vs non-Pro) and which endpoints you need. The key is: use the Identity service’s HttpApi.Client (client proxy) for remote calls, not EF 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.
In a microservice solution you generally should not create an EF Core navigation property / foreign key to IdentityUser inside another microservice’s database, because IdentityUser lives in the Identity microservice (its own bounded context + its own database). That’s why ABP Studio/Suite doesn’t offer “Identity” as a selectable module entity for a navigation property in your WorkItem entity designer.
The recommended approach is:
AssignedUserId : Guid in WorkItem (as you already do).AssignedUserId -> UserName (or Name + Surname, etc).public class WorkItemDto : EntityDto<Guid>
{
public Guid? AssignedUserId { get; set; }
public string? AssignedUserName { get; set; } // <- add this
}
AssignedUserIds.AssignedUserName.(How you call Identity depends on your solution’s existing microservice client setup, but conceptually you do a remote call to Identity’s user endpoints and join in-memory.)
Volo.Abp.Identity.IdentityUser in another microservice’s domain model to create an EF relationship.ABP Studio’s low-code “Reference Entities” list includes Identity User as a reference entity (for lookup/display purposes), not as a local EF navigation target in another microservice DB:
Volo.Abp.Identity.IdentityUser (typical display property: UserName)Validated source:
Validated source:
There is an article showing adding a user navigation property via Suite in a monolith-style setup (where user entity is in the same solution/bounded context). This is generally not the right model for microservices:
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.
CMS Kit Pro Newsletter is a subscription management feature (subscribe/unsubscribe, list subscribers, export to CSV). It does not include built-in email delivery / campaign management (no “create campaign”, “compose email”, “send to subscribers” UI or app service in the module).
Recommended approach is to implement your own “campaign sender” (or integrate an external provider) and use CMS Kit Pro Newsletter only as the subscriber store:
IEmailSender), typically via QueueAsync(...) to avoid blocking and to use background jobs.If you don’t want to build this yourself, the practical alternative is exactly what you suggested: export subscribers (CSV) and use an external email marketing provider (SendGrid / Mailchimp / etc.) for campaigns, scheduling, analytics, throttling, bounce handling, etc.
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 React UI, the Setting Management page does not automatically create a new tab/group just because you added SettingDefinitions. Defining settings only makes them available to the backend (and to the client if isVisibleToClients: true), but the admin UI tabs are contributed explicitly by the UI package/module.
The recommended/standard way to add a new “tab” (group) in the Administration → Settings (Setting Management) UI is:
SendGridSettingDefinitionProvider).ISettingProvider + ISettingManager).pSendGridSettings.tsx under src/pages/settings, that won’t work unless your React app’s routing/menu is configured to load it.Backend part (what you should keep / adjust):
isVisibleToClients: true for non-secret values.isEncrypted: true for ApiKey (good).Practical approach for React (works reliably):
public class SendGridSettingsAppService : ApplicationService
{
private readonly ISettingProvider _settingProvider;
private readonly ISettingManager _settingManager;
public SendGridSettingsAppService(ISettingProvider settingProvider, ISettingManager settingManager)
{
_settingProvider = settingProvider;
_settingManager = settingManager;
}
public async Task<SendGridSettingsDto> GetAsync()
{
return new SendGridSettingsDto
{
Enabled = await _settingProvider.GetAsync<bool>(SendGridSettings.Enabled),
FromName = await _settingProvider.GetOrNullAsync(SendGridSettings.FromName),
FromAddress = await _settingProvider.GetOrNullAsync(SendGridSettings.FromAddress),
ApiKey = await _settingProvider.GetOrNullAsync(SendGridSettings.ApiKey)
};
}
public async Task UpdateAsync(SendGridSettingsDto input)
{
await _settingManager.SetGlobalAsync(SendGridSettings.Enabled, input.Enabled.ToString());
await _settingManager.SetGlobalAsync(SendGridSettings.FromName, input.FromName);
await _settingManager.SetGlobalAsync(SendGridSettings.FromAddress, input.FromAddress);
await _settingManager.SetGlobalAsync(SendGridSettings.ApiKey, input.ApiKey);
}
}
(Then generate the React service proxies and build a custom admin page that calls `GetAsync/UpdateAsync`.)
Sources (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.
This exception is not an ABP-specific bug; it’s coming from ASP.NET Core Data Protection during Blazor Server prerendering/persisted state (ComponentStatePersistenceManager.PersistStateAsync()), when it tries to encrypt data:
CryptographicException: ... encrypt the provided dataCould not load file or assembly 'Microsoft.Win32.Registry, Version=8.0.0.0'The reason Swagger works but “the page” fails is that Swagger is just serving middleware/UI and usually doesn’t hit Blazor Server prerender persistence. The Blazor page pipeline does, so it triggers Data Protection encryption.
Ensure the app is running with the full .NET 8 runtime (not trimmed / not missing framework assemblies).
Microsoft.Win32.Registry runtime assembly isn’t available (common with certain Linux/container publish setups or incorrect runtime installation).If you deploy with Docker, use an official ASP.NET 8 runtime base image (so the runtime packs include needed assemblies), e.g. mcr.microsoft.com/dotnet/aspnet:8.0 (or matching patch).
Configure Data Protection key storage explicitly (especially for IIS/containers), so key ring operations don’t rely on defaults that may differ per environment.
*.Web (Blazor Server) project module or Program.cs, configure DataProtection to persist keys to a known folder (mounted volume in containers; writable folder in IIS):using Microsoft.AspNetCore.DataProtection;
using System.IO;
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(builder.Environment.ContentRootPath, "DataProtection-Keys")));
DataProtection-Keys (or your chosen path).If you are also loading openiddict.pfx in production, ensure IIS can load the cert and the private key correctly (this often requires Load User Profile = true and/or key storage flags). ABP has a dedicated guidance for this scenario and it’s closely related to crypto failures on IIS.
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.
Issue 1 (Shared Accounts – “Leave Tenant” doesn’t update Host user / tenant list still shown):
With Shared User Accounts (TenantUserSharingStrategy.Shared), the “leave tenant” action doesn’t primarily rely on flipping the Leaved flag on a tenant AbpUsers row. Instead, ABP maintains a host-side membership/association for the user↔tenant relationship, and “Leave” marks that membership as left so the tenant no longer appears in the tenant switcher list.
In your migration, you manually created host AbpUsers rows for tenant users (which is required for database-per-tenant scenarios), but for pre-migration tenants it sounds like the user↔tenant association data wasn’t created/matched correctly. As a result, the “Leave Tenant” operation updates something in the tenant DB (you see Leaved = 1), but the host-side association that drives the visible tenant list remains effectively “joined”.
What to do (verified approach):
UserId across host and tenant databases, host will still think the user is a member, and the tenant will remain visible after login.Issue 2 (No “Delete” action for users in Identity Management UI):
In ABP, deleting identity users from the UI is typically governed by permissions. If the current admin account doesn’t have the delete permission, the UI won’t show the delete action.
What to do:
admin) and open Permissions.Sources (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.
AppUrlOptions is the correct/expected way to make Account module email links (forgot password / reset password / email confirmation, etc.) point to the correct UI host, including tenant-specific subdomains.AppUrlOptions + IAppUrlProvider). If options.Applications["MVC"].RootUrl (or your relevant UI key) is set to a non-tenant-aware host URL, the generated link will also be non-tenant-aware—exactly what you observed.To make links tenant-aware for a subdomain setup, setting a template RootUrl is the right approach, e.g.:
Configure<AppUrlOptions>(options =>
{
// Use the UI application's key that Account uses for link generation in your solution
options.Applications["MVC"].RootUrl = "https://{0}.example.com";
});
{0} is the placeholder ABP uses to inject the current tenant name when generating URLs (similar to how it’s used in the domain/subdomain tenant resolver).IAppUrlProvider), which is typically what you want in a subdomain-per-tenant setup.AppUrlOptions.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.