Back to Abp

ABP Version 10.4 Migration Guide

docs/en/release-info/migration-guides/abp-10-4.md

10.4.014.2 KB
Original Source
json
//[doc-seo]
{
    "Description": "Upgrade your ABP solutions from v10.3 to v10.4 with this migration guide covering important behavior and integration changes."
}

ABP Version 10.4 Migration Guide

This document is a guide for upgrading ABP v10.3 solutions to ABP v10.4. There are no explicitly marked breaking changes in this release scope, but there are some important changes that may require action in specific application scenarios.

Package Version Changes: Before upgrading, review the Package Version Changes document to see version changes on dependent NuGet packages and align your project with ABP's internal package versions.

Open-Source (Framework)

This version contains the following changes on the open-source side:

URL-Based Localization

Who is affected

  • Applications that enable the new URL-based localization option.
  • Blazor applications with custom routable pages.
  • Angular applications that need culture-prefixed URLs.

What changed

  • ABP now supports embedding the culture in the URL path, such as /en/products or /tr/identity/users.
  • The feature is opt-in and disabled by default.
  • MVC and Razor Pages are handled automatically when enabled.
  • ABP built-in Blazor module pages include culture-aware routes, but your own Blazor pages need manual route variants.
  • Angular applications should wrap routes and culture-aware links with the new Angular helpers.

What to do

If you do not enable URL-based localization, no action is required.

If you enable it, configure AbpRequestLocalizationOptions:

csharp
Configure<AbpRequestLocalizationOptions>(options =>
{
    options.UseRouteBasedCulture = true;
});

For custom Blazor pages, add culture route variants:

razor
@page "/Products"
@page "/{culture}/Products"

For Angular applications, wrap your route tree with withOptionalRouteCulturePrefix from @abp/ng.core, and use the route-culture URL helpers/pipes for menu links, breadcrumbs, and language switching.

See the URL-Based Localization document and #25174 for details.

Localization JSON Files Can Be Split by Culture

Who is affected

  • Applications/modules that want to split a large localization resource into multiple JSON files for the same culture.
  • Applications that already have duplicate culture JSON files under the same localization resource path.

What changed

  • ABP now allows multiple JSON files with the same culture value under the same localization resource.
  • Files are merged in ordinal name order.
  • If the same localization key exists in multiple files, the value from the last file wins.

What to do

No action is required for existing applications.

If you split localization files, choose deterministic file names and avoid unintended duplicate keys:

text
Localization/
+-- MyResource/
    +-- en.json
    +-- en_Authors.json
    +-- en_Books.json

See #25227 for details.

Email/SMS 2FA Codes Are Single-Use

Who is affected

  • Applications using the Identity module's email or phone 2FA providers.
  • Applications with custom flows around phone-number change tokens.
  • Applications that replace or customize ASP.NET Core Identity token providers.

What changed

  • ABP replaces the default email and phone 2FA providers with DataProtector-backed single-use providers.
  • Generated codes are encrypted, persisted with an absolute expiration, and removed after successful validation.
  • Generating a new code invalidates the previous one.
  • UserManager.GenerateChangePhoneNumberTokenAsync / VerifyChangePhoneNumberTokenAsync also inherit the new stored-token semantics because ASP.NET Core Identity uses the default phone provider for phone-number changes.
  • Phone-change tokens issued before upgrading may stop working after the upgrade.

What to do

  • Re-test login, email 2FA, SMS 2FA, and phone-number change flows.
  • If your application needs a different code lifetime or length, configure the new provider options:
csharp
Configure<AbpEmailTwoFactorTokenProviderOptions>(options =>
{
    options.TokenLifespan = TimeSpan.FromMinutes(5);
    options.CodeLength = 8;
});

Configure<AbpPhoneNumberTwoFactorTokenProviderOptions>(options =>
{
    options.TokenLifespan = TimeSpan.FromMinutes(2);
});
  • If your application requires custom token behavior, replace the token provider by registering your own provider under TokenOptions.DefaultEmailProvider and/or TokenOptions.DefaultPhoneProvider.

See the Two Factor Authentication document and #25316 for details.

MudBlazor Support for Blazor UI

Who is affected

  • Blazor applications that want to try the new MudBlazor-based ABP UI support.
  • Module authors who build Blazor UI packages and want to support MudBlazor.

What changed

  • ABP v10.4 introduces the initial MudBlazor integration packages, templates, bundling infrastructure, and module/theme support.
  • Existing Blazorise-based applications are not automatically migrated to MudBlazor.

What to do

  • No action is required for existing Blazorise-based applications.
  • If you want to try MudBlazor support, create a new v10.4 RC solution/template or add the related MudBlazor packages according to the target UI type and test the UI carefully before production usage.

See #25235 for details.

Text Template Rendering Engine — IsSandboxed Marker

Who is affected

  • Custom rendering engines that implement Volo.Abp.TextTemplating.ITemplateRenderingEngine directly (not deriving from TemplateRenderingEngineBase).
  • Modules and applications that surface template editing to non-developer users (e.g. the Text Template Management module).

What changed

  • ITemplateRenderingEngine exposes a new required property:

    csharp
    bool IsSandboxed { get; }
    

    Sandboxed engines (e.g. Scriban) interpret templates as a restricted DSL without .NET interop. Non-sandboxed engines (e.g. Razor) compile templates into fully-trusted .NET code that runs with the same privileges as the host process.

  • TemplateRenderingEngineBase provides a virtual default of false (secure-by-default): engines that derive from the base class and don't override the property are treated as non-sandboxed.

  • RazorTemplateRenderingEngine declares IsSandboxed => false (compiles to .NET assembly via Roslyn).

  • ScribanTemplateRenderingEngine declares IsSandboxed => true and now sets Scriban's TemplateContext.MemberFilter so only public properties on imported objects are exposed; methods, fields, events and reflection entry points (GetType, Assembly, ...) are no longer reachable from Scriban templates.

What to do

  • If your application registers a custom engine by implementing ITemplateRenderingEngine directly (without deriving from TemplateRenderingEngineBase), add the property:

    csharp
    public bool IsSandboxed => false; // or true if your engine cannot execute host code
    
  • If your engine derives from TemplateRenderingEngineBase, no action is required for compilation; however, override IsSandboxed => true if your engine is genuinely sandboxed so callers (such as the Text Template Management module) treat its templates as safe to edit by non-developer users.

  • Scriban templates that invoke methods on the model (e.g. {%{{{ model.SomeMethod }}}%}) or read fields stop working because the engine now whitelists public properties only. Templates that access only properties (the typical Scriban usage) are unaffected. To restore the previous behavior in custom hosts, derive from ScribanTemplateRenderingEngine and override IsMemberAllowed to allow methods or fields:

    csharp
    protected override bool IsMemberAllowed(MemberInfo member) => true;
    

    Only do this when the model objects are trusted and do not carry secrets, since the previous behavior exposed reflection entry points (GetType, Assembly, ...) on imported .NET objects.

See #25399 for details.

Text Template Management — EditContents Permission Split (security)

Who is affected

  • Applications using the Text Template Management module that have granted the TextTemplateManagement.TextTemplates.EditContents permission to roles that are not fully trusted server administrators/developers.
  • In particular, applications that use Razor templates (default for solutions referencing Volo.Abp.TextTemplating.Razor) and have any non-developer role with EditContents.

What changed

  • A new permission TextTemplateManagement.TextTemplates.EditNonSandboxedContents has been added.
  • Editing a template whose rendering engine is non-sandboxed (i.e. ITemplateRenderingEngine.IsSandboxed == false, e.g. Razor) now requires both permissions: EditContents and EditNonSandboxedContents.
  • The new permission is not granted to any role by default, including the admin role. The previously implicit assumption — that EditContents was enough to edit Razor templates — has been corrected: editing such templates is functionally equivalent to granting server-side code execution and is now gated by an explicit permission whose name communicates that risk.
  • The Text Template Management UI (MVC, Blazor) renders a security warning banner when the current template's engine is non-sandboxed, and disables the save/restore buttons when the current user lacks the new permission.

What to do

After upgrading, audit which roles currently hold EditContents and decide which of them should also be granted EditNonSandboxedContents:

  1. Roles that should only edit sandboxed templates (e.g. Scriban, Liquid, plain HTML) need no further action — they keep editing those templates.

  2. Roles that need to continue editing Razor templates must be granted EditNonSandboxedContents explicitly via the Permission Management page.

  3. If — and only if — you have reviewed your role assignments and confirmed that every role currently holding EditContents is trusted to execute server-side code through Razor templates, you may seed the new permission for those roles via your IDataSeedContributor:

    csharp
    var grants = await _permissionGrantRepository.GetListAsync(
        TextTemplateManagementPermissions.TextTemplates.EditContents);
    
    foreach (var grant in grants)
    {
        await _permissionManager.SetAsync(
            TextTemplateManagementPermissions.TextTemplates.EditNonSandboxedContents,
            grant.ProviderName,
            grant.ProviderKey,
            isGranted: true);
    }
    

Do not automate this seeding for arbitrary tenants/roles without first reviewing the current grants — auto-restoring the previously-implicit elevated trust would defeat the security improvement. The recommended path is to grant the new permission only to specific developer/operator roles via the Permission Management UI.

If your application's data seeder grants all permissions in the TextTemplateManagement group to a role (e.g. the admin role), that role will automatically receive EditNonSandboxedContents on first run after upgrade. Audit your seeder if you want stricter defaults.

See the Razor Integration document and #25399 for details.

Dependency Updates

Who is affected

  • Applications that pin ABP transitive dependencies directly.
  • Applications that use OpenIddict, MongoDB, or Microsoft/System packages directly with fixed versions.

What changed

  • OpenIddict was upgraded to 7.5.0.
  • MongoDB.Driver was upgraded to 3.8.0.
  • Several Microsoft/System packages were upgraded to 10.0.7 for CVE-2026-40372.
  • System.Security.Cryptography.Xml was upgraded to 10.0.6.

What to do

  • Review your direct package references and align them with ABP's package versions where needed.
  • Rebuild and run integration tests if you directly use upgraded packages.

Pro

There are no explicitly marked breaking changes on the PRO side in this release scope. However, check the following if they apply to your application.

Account Pro Passwordless Email Login

Who is affected

  • Applications using the Account Pro module that want to enable passwordless email login.

What changed

  • Account Pro now supports email login by one-time link, one-time password (OTP), or both.
  • The feature is disabled unless configured.
  • Tokens are single-use, expire according to the configured lifetime, and respect tenant-scoped settings.

What to do

  • No action is required if you do not enable passwordless email login.
  • If you enable it, review account settings, email templates, token lifetime, rate limiting, and PreventEmailEnumeration behavior.
  • Re-test login flows for host and tenant users.

QA Module AI Suggest

Who is affected

  • Applications using the QA module and enabling AI-assisted answer suggestions.

What changed

  • Authorized users can generate AI-suggested answers based on question context and existing answers.
  • The feature is controlled by settings and permissions.

What to do

  • No action is required unless you enable the feature.
  • If enabled, configure the QA AI Suggest settings, prompt, character limits, and permissions.

AI Management MCP Server Enhancements

Who is affected

  • Applications using the AI Management module's MCP server integration.

What changed

  • MCP server configuration was enhanced for stdio transport scenarios and workspace relationships.

What to do

  • Re-test MCP server connection, tool listing, and workspace chat flows after upgrading.

LeptonX URL-Based Localization Support

Who is affected

  • Applications using LeptonX with URL-based localization.

What changed

  • LeptonX has been updated for culture-aware navigation and language switching, including Angular support.
  • Several menu, select, sidebar, and PathBase-related fixes were included.

What to do

  • If you enable URL-based localization, re-test language switching, menu links, breadcrumbs, and PathBase deployments for your UI type.