Activities of "AI-Bot"

  • Enable ABP Conventional Controllers in your Web/HttpApi.Host module (i.e., the module that hosts ASP.NET Core MVC) by configuring AbpAspNetCoreMvcOptions and calling options.ConventionalControllers.Create(...).
  • The most common place is the PreConfigureServices method of your *.WebModule (or *.HttpApiHostModule).
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;

[DependsOn(typeof(MyProjectApplicationModule))]
public class MyProjectWebModule : AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        PreConfigure<AbpAspNetCoreMvcOptions>(options =>
        {
            options.ConventionalControllers.Create(typeof(MyProjectApplicationModule).Assembly);
        });
    }
}

Notes:

  • Use the Application assembly (where your AppServices are) in Create(...) so ABP can generate API controllers for those application services.

  • If you’re in a tiered solution, you typically put this in HttpApi.Host (not the MVC UI project), because that’s where the APIs are exposed.

  • https://abp.io/docs/latest/framework/api-development/auto-controllers


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.

  • You generally don’t need to change the ASP.NET Core pipeline to “use controllers/views instead of Razor Pages” in ABP. ABP MVC UI already runs on the same MVC infrastructure; Razor Pages are just additional endpoints.
  • What you do in practice is:
    1. Ensure MVC controllers + views are enabled.
    2. Stop mapping Razor Pages endpoints (or just don’t create any Razor Pages routes/content), then route everything through controllers.

1) Configure endpoints to map controllers (and optionally stop mapping Razor Pages)

In your Web project Program.cs (or the equivalent in your ABP host), ensure you have endpoint routing and map controller routes:

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseConfiguredEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    // If you want to prevent Razor Pages endpoints from being reachable,
    // do NOT map Razor Pages:
    // endpoints.MapRazorPages();
});

If your solution currently maps Razor Pages somewhere (some templates do), removing MapRazorPages() will stop Razor Page endpoints from being matched.

2) Ensure MVC controllers are discovered (ABP conventional controllers – optional but common)

If you want ABP to automatically expose your Application Services as HTTP APIs (common when building controller/view UIs that call backend APIs), make sure conventional controllers are enabled:

Configure<AbpAspNetCoreMvcOptions>(options =>
{
    options.ConventionalControllers.Create(typeof(MyProjectApplicationModule).Assembly);
});

This is especially relevant in “public web” style setups where proxies/controllers may not be created by default.

3) Move/implement UI routes as controllers + views

Once the endpoints are mapped, the rest of the “conversion” is purely at the feature level:

  • Replace Pages/... Razor Pages with Controllers/...Controller.cs
  • Create Views/.../*.cshtml
  • Update links from asp-page="..." to asp-controller / asp-action

(light) verified references

  • https://abp.io/docs/latest/framework/ui/mvc-razor-pages/theming
  • https://abp.io/docs/latest/release-info/migration-guides/abp-5-2
  • https://abp.io/support/questions/959

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, MVC Controllers + Views and Razor Pages are both hosted by the same ASP.NET Core MVC stack. There isn’t a “switch” that automatically converts a Razor Pages UI into controller-based MVC UI. The conversion is essentially: stop creating/using Pages/*.cshtml endpoints and implement the same endpoints as Controllers/*Controller.cs + Views/*/*.cshtml (while keeping ABP’s theme/bundling/layout infrastructure).
  • Below is a practical, step-by-step conversion approach that keeps ABP Commercial and moves your UI to controller-based MVC.

1) Keep ABP as-is; just stop using Razor Pages routes

  1. Leave all ABP modules, authentication (AuthServer/OpenIddict), localization, theming, etc. intact.

  2. For each UI feature currently implemented as Razor Pages:

    • Pages/Foo/Index.cshtml (+ Index.cshtml.cs)
    • Pages/Foo/Create.cshtml (+ Create.cshtml.cs)
    • Pages/Foo/Edit.cshtml (+ Edit.cshtml.cs)

    You will create:

    • Controllers/FooController.cs
    • Views/Foo/Index.cshtml
    • Views/Foo/Create.cshtml
    • Views/Foo/Edit.cshtml
  3. Once the controller routes work, you can delete (or ignore) the old Razor Pages under Pages/ to avoid duplicate endpoints.


2) Convert each Razor PageModel into an MVC Controller action

Example mapping

Razor Page

  • URL: /Books
  • Files: Pages/Books/Index.cshtml and Pages/Books/Index.cshtml.cs

MVC

  • URL: /Books
  • Files: Controllers/BooksController.cs and Views/Books/Index.cshtml

Controller skeleton (ABP-style)

using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;

namespace MyCompany.MyProject.Web.Controllers;

[Route("[controller]")]
public class BooksController : AbpController
{
    [HttpGet]
    [Route("")]
    public IActionResult Index()
    {
        return View();
    }

    [HttpGet]
    [Route("Create")]
    public IActionResult Create()
    {
        return View();
    }
}

Key ABP point: keep your business logic in Application Services (e.g., IBookAppService). Your controller should call application services and pass view models to views.


3) Replace asp-page usages with MVC equivalents

In ABP Razor Pages UIs, you often see:

  • asp-page="/Books/CreateModal"
  • Url.Page(...)

When you move to controllers:

  • Use asp-controller="Books" asp-action="Create" or Url.Action(...).

Example:

<a class="btn btn-primary" asp-controller="Books" asp-action="Create">New Book</a>

4) If your UI currently uses “Create/Edit modal” Razor Pages, convert to full pages (or keep modal behavior)

ABP templates commonly use “CreateModal / EditModal” Razor Pages (opened via JS modal manager). If you want controller-based pages, a proven approach is to turn those modals into normal pages (and then you can further convert to controllers if you want).

A community article shows exactly how to convert ABP modal pages into regular pages by:

  • changing links/actions to navigate with URL
  • removing modal-manager JS parts
  • wrapping the modal markup so it renders as a page

(Use the technique/pattern, then you can translate the endpoint from Razor Page to MVC Controller.)

This reference includes a working commit you can follow.


5) Keep ABP theme/layout/bundling; just render Views instead of Pages

Even when you move to controllers+views, ABP’s theming/bundling still applies.

  • Your views should continue to use the same shared layouts (Basic/LeptonX) unless you override them.
  • You can override theme layouts by copying the layout file into your project using the same virtual path (ABP VFS override mechanism). This is the standard way to apply a corporate HTML theme.

(You’ll typically override Themes/.../Layouts/... and configure AbpBundlingOptions to add your CSS/JS.)


6) Validate routing and remove Razor Pages endpoints

Once your controller routes are ready:

  • Remove the corresponding Pages/... files, or at least ensure you’re not linking to them anymore.
  • Test that navigation, authorization, localization, and static resources still work.

(light) verified references

  • https://abp.io/docs/latest/framework/ui/mvc-razor-pages/theming
  • https://abp.io/community/articles/4ps5v60m
  • https://github.com/abpframework/abp-samples/commit/f3014e0ec422cb2d8816d0e00dd6ab9cc1adfc21

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 Commercial (ABP Platform) is not designed to be installed into an arbitrary existing ASP.NET Core MVC project “piece by piece”. The supported, step-by-step manual way is to create an ABP Commercial solution with the ABP Startup Template (MVC + EF Core + SQL Server) and then move your MVC code into that solution (controllers/views/static files), or expose your existing code through ABP application services/modules.
  • If what you mean by “manual install” is “add commercial modules manually (without ABP CLI) into an ABP solution”, then you can do that by adding the relevant Volo.* NuGet packages and module dependencies (example below).

Option A (Supported): Create an ABP Commercial MVC solution, then migrate your project into it

  1. Install ABP CLI (if not installed) and login (commercial feed access comes from your account/license).
  2. Create a new ABP MVC solution (EF Core + SQL Server):
abp new MyCompany.MyProject --ui mvc --database-provider ef
  1. Configure SQL Server connection string in *.DbMigrator (and host/web if needed), then run the migrator to create DB + seed admin user.
  2. Copy/merge your existing MVC project assets into the ABP Web project:
    • Controllers (preferably convert business logic to Application Services and keep controllers thin)
    • Views / Pages
    • wwwroot, bundling/layout changes
  3. Re-implement auth/permissions using ABP’s authorization system (policies/permissions) and Identity/OpenIddict as needed.

Option B: “Manual installation” of a Commercial module (pattern) inside an ABP MVC solution

If you already have an ABP MVC solution and want to add a commercial module manually (without abp add-module), the general steps are:

  1. Add the module NuGet package(s) to the correct layer(s) (Application / Domain / EFCore / Web, etc.)
  2. Add the module class to the DependsOn(...) attribute of your module classes.
  3. If the module has EF Core integration, call its builder.ConfigureXxx() inside your DbContext.OnModelCreating.
  4. Add the module’s NPM package (if it has an MVC UI) and run library install.

Example (from the official “File Management Module (Pro) – Manual Installation” approach):

  1. Add package reference (example: to *.Application.csproj):
<PackageReference Include="Volo.FileManagement.Application" Version="x.x.x" />
  1. Add dependency in your module class (example: *.ApplicationModule):
[DependsOn(
    // ...
    typeof(FileManagementApplicationModule)
)]
public class MyProjectApplicationModule : AbpModule
{
}
  1. EF Core model configuration in your DbContext:
protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.ConfigureFileManagement();
}
  1. Add NPM package to package.json (Web project):
"dependencies": {
  "@volo/file-management": "^2.9.0"
}
  1. Then run (in the Web project folder):
abp install-libs

Sources

  • https://abp.io/docs/latest/CLI
  • https://abp.io/docs/10.2/modules/file-management

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.

  • Yes. ABP automatically applies Unit of Work (UOW) to all public application service methods by convention, regardless of whether the method is “Get”/read-like or “Create/Update/Delete”. So your Get... method is inside a UOW scope too.

  • However, being inside a UOW doesn’t always mean a DB transaction is started. With the default UnitOfWorkTransactionBehavior.Auto behavior for HTTP requests, GET HTTP requests don’t start a transactional UOW by default. That said, you can still write to the database inside a GET method, and it can still cause locks/contention and timeouts (especially if that GET endpoint is hit frequently).

What you should do in your case (since your GET calls UpdateAsync)

  1. Don’t update data inside a GET. Move that update logic to a separate command endpoint (POST/PUT), or a background job/event handler.
  2. If you must keep it temporarily, explicitly control the UOW/transaction behavior:
    • Disable UOW for that GET if it should be pure read:
[UnitOfWork(IsDisabled = true)]
     public virtual async Task<AgentDto> GetAsync(Guid id)
     {
         // read-only code only
     }
  • Or if it truly must update, make it a non-GET endpoint and/or force transactional UOW explicitly (so the behavior is clear and consistent).

This pattern (UOW on application service methods + GET requests not starting transactions by default) is documented in ABP’s Unit of Work docs.

Sources:

  • https://abp.io/docs/latest/framework/architecture/domain-driven-design/unit-of-work
  • https://abp.io/community/articles/0r248xsr

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.

  • Create a separate, mobile-optimized UI project (don’t try to “force” the existing ABP Angular UI to be mobile-first). Keep the existing ABP Angular app for desktop/admin use, and build a dedicated Mini App UI that consumes the same microservice backends.
  • If you want to stay in the Angular ecosystem and target a WebView / mobile UI, the most ABP-friendly approach is to create an Ionic Angular (or any custom Angular) app and integrate ABP Angular packages:
    1. Create the new mobile UI (e.g., Ionic Angular).
    2. Install ABP Angular core packages in the new UI:
      • @abp/ng.core (authentication helpers, RestService, localization, permission checks, etc.)
      • @abp/ng.schematics (to generate API proxies)
    3. Configure the new UI’s environment.ts with your ABP AuthServer/IdentityServer settings (issuer, clientId, redirectUri, scope, and apis.default.url).
    4. Register a separate OAuth client for the Mini App (a new ClientId) in your AuthServer/IdentityServer seeding (and allow the Mini App origin in CORS / redirect URLs).
    5. Generate API proxies for the new UI using ABP CLI (so you can strongly-type your HTTP calls against your existing services):
abp generate-proxy -t ng -m identity -u https://<your-authserver-or-gateway-url>
  1. Use ABP Angular AuthService to redirect to login, and use the generated proxies (or RestService) for API integration.
  • This gives you maximum reuse of ABP infrastructure while letting you fully redesign the UI for mobile:
    • Authentication/OIDC flow stays standard ABP (redirect to AuthServer login page from the WebView).
    • API integration via ABP-generated Angular proxies.
    • Localization/permission checks/config state via @abp/ng.core.
    • You only rebuild the UI layer with a mobile component library/layout.

Links (verified):

  • https://abp.io/community/articles/ix98a3rr
  • https://abp.io/docs/latest/solution-templates/application-module/

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.

  • No—a timeout is not caused by ConcurrencyStamp itself. ConcurrencyStamp is just an optimistic concurrency token (a string) that EF Core includes in the WHERE clause to ensure “update only if nobody else changed it”. If the stamp doesn’t match, you get an AbpDbConcurrencyException / DbUpdateConcurrencyException (0 rows affected), not a 30s timeout.

  • A 30-second timeout on this statement almost always means SQL Server is waiting on locks (blocking) or being throttled. Even a single-row update can sit and wait if:

    • another transaction holds a lock on that row (or a broader lock due to escalation),
    • a long-running transaction/UOW is open in your service,
    • you have multiple microservice instances/background workers updating the same row(s),
    • Azure SQL is under resource pressure.

What to do (actionable, ABP-relevant):

  1. Confirm it’s blocking (most likely) When the timeout happens, you should see the session in a WAIT state (e.g., LCK_M_...) on Azure SQL. If it’s blocking, the fix is to find and eliminate the long transaction / hot row contention (not to change concurrency stamp behavior).

  2. Increase the EF Core command timeout (mitigation) Configure ABP’s DbContext options to raise command timeout so transient blocking/throttling doesn’t fail at 30 seconds:

using Volo.Abp.EntityFrameworkCore;

   Configure<AbpDbContextOptions>(options =>
   {
       options.Configure(cfg =>
       {
           cfg.DbContextOptionsBuilder.CommandTimeout(180);
       });
   });
  1. If the same “Agent” row is frequently updated, prevent multi-instance contention In microservices with multiple replicas, if many workers update the same entity (same Id) you can get lock queues and timeouts. In such cases, you typically need to redesign to reduce hot-row updates (e.g., avoid repeatedly updating audit/concurrency fields for “heartbeat”-like writes), or use a distributed locking / coordination approach around that critical section.

(Concurrency token docs, validated)

  • https://abp.io/docs/latest/framework/infrastructure/concurrency-check
  • https://abp.io/community/articles/jlkc3w8f

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.

  • The SQL you posted is an optimistic concurrency update generated by EF Core (ABP uses ConcurrencyStamp on aggregate roots like IdentityUser, etc.). A timeout on a single-row UPDATE ... WHERE Id AND ConcurrencyStamp with ~900 rows is almost never caused by table size; it’s typically caused by blocking/locking (another transaction holds a lock on that row/table) or resource pressure (DTU/vCore throttling) on Azure SQL after the upgrade.

  • With ABP 10 you are very likely also on a newer .NET/EF Core version than ABP 8 (EF Core 8 vs EF Core 6/7 depending on your starting point). That doesn’t “break” this statement, but it can change overall behavior (more queries, different batching, different execution plans), which can expose existing locking issues under load.

Do these ABP-specific fixes/mitigations (safe and commonly used):

  1. Increase EF Core command timeout for ABP DbContexts Configure it in your *.EntityFrameworkCore module where you call Configure<AbpDbContextOptions>:
using Volo.Abp.EntityFrameworkCore;

   public override void ConfigureServices(ServiceConfigurationContext context)
   {
       Configure<AbpDbContextOptions>(options =>
       {
           options.Configure(cfg =>
           {
               // Increase as needed (seconds)
               cfg.DbContextOptionsBuilder.CommandTimeout(180);
           });
       });
   }

This doesn’t solve blocking, but prevents “false failures” during short spikes/throttling.

  1. Identify and remove blocking transactions (most common root cause) In Azure SQL, check for blocking at the time of the issue (Query Store / “Blocked process” views / running requests). The symptom you see (timeout on a simple update with concurrency check) is consistent with:

    • a long-running UOW/transaction holding locks,
    • a background worker / migration / seed running concurrently,
    • or multiple services updating the same “Agent” row(s) frequently.

    ABP microservices commonly use distributed events/outbox patterns; if you have a consumer that updates the same entity repeatedly inside a long unit-of-work, it can block other writers.

  2. Ensure your Azure SQL tier/performance didn’t effectively downgrade After upgrade, overall DB activity usually increases (more features/modules, more permission/setting/cache reads/writes). On low tiers, Azure SQL may throttle and cause timeouts even on trivial statements.

  3. Make sure SQL Server compatibility is supported ABP 8 migration notes remind that starting with EF Core 8.0, generated SQL requires newer SQL Server versions (SQL Server 14+). Azure SQL with compat level 2019 is fine, but this confirms the “version support” angle is not your problem here—again pointing back to blocking/throttling.

If you apply (1) and still see timeouts, treat it as a blocking/throttling problem rather than an ABP/EF bug: the specific statement is a single-row concurrency update, so it should complete instantly unless it’s waiting.

Links (verified):

  • https://abp.io/docs/latest/release-info/migration-guides/abp-8-0
  • https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/breaking-changes#high-impact-changes

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 the microservice solution, permissions are registered to the permission definition tables by the related microservice when it starts (assuming PermissionManagementOptions.SaveStaticPermissionsToDatabase is true, which is the default).
  • However, granting those permissions to the admin role is not done by every microservice. By design, only the Administration microservice seeds/grants permissions to the admin role. So it’s expected to see permissions defined/registered, but no rows in AbpPermissionGrants for admin until Administration performs the seeding.

What to do (definitive steps):

  1. Start/restart the Administration microservice

    • After you first run everything (or after enabling new modules like Language Service / AI Management), restart Administration.
    • On restart, Administration will grant newly discovered permissions to the admin role automatically (or you can grant them manually in the UI).
  2. If you are using Redis/distributed cache, clear it

    • In microservice solutions, permission definition/grant info is cached. If you don’t see the new permission groups in the UI (Role Permissions dialog) even after restart, clear Redis (or your configured distributed cache), then restart the services again.
  3. (Optional, if you want it always automatic per service) Create a data seeder that uses IPermissionDataSeeder

    • If you want LanguageService and AIManagement service permissions to be auto-granted without relying on restarting Administration, add a custom data seeder in the appropriate service and call IPermissionDataSeeder to grant permissions to the admin role (the same approach referenced in the microservice permission management doc).

Links (validated):

  • https://abp.io/docs/10.2/solution-templates/microservice/permission-management
  • https://abp.io/docs/10.2/solution-templates/microservice/localization-system
  • https://abp.io/docs/10.2/modules/ai-management/

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.

They are inside the Basic Theme package’s embedded resources. In the ABP Framework source code, you can see (and copy from) them here:

  • Basic Theme root project (contains all the .cshtml files):
    modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic

  • Layouts (.cshtml):
    modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts
    (e.g., Themes/Basic/Layouts/Application.cshtml, Themes/Basic/Layouts/Account.cshtml)

  • Theme view components (.cshtml):
    modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/...
    (e.g., navbar, toolbar, brand, etc.)

To override any of these in your app, create the same relative path in your Web project (e.g., Themes/Basic/Layouts/Application.cshtml) and your file will override the theme’s embedded one.

  • https://github.com/abpframework/abp/tree/dev/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
  • https://github.com/abpframework/abp/blob/dev/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts
  • https://abp.io/docs/latest/framework/ui/mvc-razor-pages/customization-user-interface

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.

Showing 341 to 350 of 1374 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on October 21, 2026, 11:09
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.