From f5c55db852bbcb2d8e8c433626a7ee6a37f9581d Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 21 Aug 2026 13:11:31 +0800 Subject: [PATCH] Add a path base matching test and document opt-in path matching --- .../AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs | 8 +++++--- .../Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs | 3 +++ .../AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs | 10 ++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs index 3784cc9005..34ba5f29c6 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs @@ -31,9 +31,11 @@ public class AbpAspNetCoreUnitOfWorkOptions /// /// Absolute request path prefixes (matched by segment) that opt-in to /// even when it is globally disabled (for example - /// "/connect" matches "/connect/token" but not "/connections"). A trailing slash is normalized; blank, - /// non-absolute, and root ("/") entries are ignored - use - /// to enable it for every request handled by the middleware. + /// "/connect" matches "/connect/token" but not "/connections"). Each prefix is matched against both + /// the request path and the path base + request path, so an endpoint configured with the path base + /// still matches. A trailing slash is normalized; blank, non-absolute, and root ("/") entries are + /// ignored - use to enable it for every request + /// handled by the middleware. /// public List CompleteUnitOfWorkOnResponseStartingUrls { get; } = new List(); } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 4339104b30..02663eae90 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -164,6 +164,9 @@ public class AbpAspNetCoreMvcTestModule : AbpModule app.UseStaticFiles(); app.UseAbpRequestLocalization(); app.UseAbpSecurityHeaders(); + // Moves the "/pathbase-test" prefix into Request.PathBase so a unit of work opt-in test can + // exercise path base matching; a no-op for every other request. + app.UsePathBase("/pathbase-test"); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs index 4e241cccf0..26f81ef3a0 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs @@ -139,4 +139,14 @@ public class UnitOfWorkMiddleware_Tests : AspNetCoreMvcTestBase var result = await GetResponseAsStringAsync("/api/unitofwork-test/CommitBeforeResponseFlush"); result.ShouldBe("first:not-completed"); } + + [Fact] + public async Task Opt_In_Url_Including_The_Path_Base_Matches() + { + // The request path is "/api/..." (the path base is stripped), so this only matches via path base + path. + Options.CompleteUnitOfWorkOnResponseStartingUrls.Add("/pathbase-test/api/unitofwork-test/CommitBeforeResponseFlush"); + + var result = await GetResponseAsStringAsync("/pathbase-test/api/unitofwork-test/CommitBeforeResponseFlush"); + result.ShouldBe("first:completed"); + } }