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");
+ }
}