diff --git a/src/Mvc/Mvc.RazorPages/src/ApplicationModels/DefaultPageApplicationModelPartsProvider.cs b/src/Mvc/Mvc.RazorPages/src/ApplicationModels/DefaultPageApplicationModelPartsProvider.cs index 5de6835aefa6..9b7ccb1284ec 100644 --- a/src/Mvc/Mvc.RazorPages/src/ApplicationModels/DefaultPageApplicationModelPartsProvider.cs +++ b/src/Mvc/Mvc.RazorPages/src/ApplicationModels/DefaultPageApplicationModelPartsProvider.cs @@ -199,8 +199,8 @@ public bool IsHandler(MethodInfo methodInfo) return false; } - // Exclude methods declared on PageModel - if (declaringType == typeof(PageModel)) + // Exclude methods declared on PageModel (including overrides) + if (methodInfo.GetBaseDefinition().DeclaringType == typeof(PageModel)) { return false; } diff --git a/src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs b/src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs index 7d304f7c0a05..e485da7156c6 100644 --- a/src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs +++ b/src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs @@ -1214,6 +1214,53 @@ public void PopulateFilters_AddsPageHandlerPageFilter_ForModelDerivingFromTypeIm [ServiceFilter(typeof(IServiceProvider))] private class DerivedFromPageModel : PageModel { } + [Fact] + public void PopulateHandlerMethods_Ignores_OverriddenPageModelLifecycleMethods() + { + // Arrange + var provider = CreateProvider(); + var typeInfo = typeof(ModelOverridingPageModelLifecycle).GetTypeInfo(); + var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, []); + + // Act + provider.PopulateHandlerMethods(pageModel); + + // Assert + // Only OnGet should be discovered as a handler. OnPageHandlerExecuting, OnPageHandlerExecuted, + // and OnPageHandlerSelected are lifecycle methods and should be excluded even when overridden. + var handlerMethods = pageModel.HandlerMethods; + Assert.Collection( + handlerMethods, + handler => + { + Assert.Equal(nameof(ModelOverridingPageModelLifecycle.OnGet), handler.MethodInfo.Name); + Assert.Equal("Get", handler.HttpMethod); + Assert.Null(handler.HandlerName); + }); + } + + private class ModelOverridingPageModelLifecycle : PageModel + { + public void OnGet() + { + } + + public override void OnPageHandlerExecuting(PageHandlerExecutingContext context) + { + base.OnPageHandlerExecuting(context); + } + + public override void OnPageHandlerExecuted(PageHandlerExecutedContext context) + { + base.OnPageHandlerExecuted(context); + } + + public override void OnPageHandlerSelected(PageHandlerSelectedContext context) + { + base.OnPageHandlerSelected(context); + } + } + private static DefaultPageApplicationModelProvider CreateProvider() { var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();