Skip to content

Commit 5b64506

Browse files
Fix: Prevent overridden PageModel lifecycle methods from being discovered as handlers (#64132)
* Initial plan * Fix: Prevent overridden PageModel lifecycle methods from being discovered as handlers Co-authored-by: MackinnonBuck <[email protected]> * Update src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: MackinnonBuck <[email protected]> Co-authored-by: Mackinnon Buck <[email protected]>
1 parent 0576690 commit 5b64506

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/Mvc/Mvc.RazorPages/src/ApplicationModels/DefaultPageApplicationModelPartsProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ public bool IsHandler(MethodInfo methodInfo)
199199
return false;
200200
}
201201

202-
// Exclude methods declared on PageModel
203-
if (declaringType == typeof(PageModel))
202+
// Exclude methods declared on PageModel (including overrides)
203+
if (methodInfo.GetBaseDefinition().DeclaringType == typeof(PageModel))
204204
{
205205
return false;
206206
}

src/Mvc/Mvc.RazorPages/test/ApplicationModels/DefaultPageApplicationModelProviderTest.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,53 @@ public void PopulateFilters_AddsPageHandlerPageFilter_ForModelDerivingFromTypeIm
12141214
[ServiceFilter(typeof(IServiceProvider))]
12151215
private class DerivedFromPageModel : PageModel { }
12161216

1217+
[Fact]
1218+
public void PopulateHandlerMethods_Ignores_OverriddenPageModelLifecycleMethods()
1219+
{
1220+
// Arrange
1221+
var provider = CreateProvider();
1222+
var typeInfo = typeof(ModelOverridingPageModelLifecycle).GetTypeInfo();
1223+
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, []);
1224+
1225+
// Act
1226+
provider.PopulateHandlerMethods(pageModel);
1227+
1228+
// Assert
1229+
// Only OnGet should be discovered as a handler. OnPageHandlerExecuting, OnPageHandlerExecuted,
1230+
// and OnPageHandlerSelected are lifecycle methods and should be excluded even when overridden.
1231+
var handlerMethods = pageModel.HandlerMethods;
1232+
Assert.Collection(
1233+
handlerMethods,
1234+
handler =>
1235+
{
1236+
Assert.Equal(nameof(ModelOverridingPageModelLifecycle.OnGet), handler.MethodInfo.Name);
1237+
Assert.Equal("Get", handler.HttpMethod);
1238+
Assert.Null(handler.HandlerName);
1239+
});
1240+
}
1241+
1242+
private class ModelOverridingPageModelLifecycle : PageModel
1243+
{
1244+
public void OnGet()
1245+
{
1246+
}
1247+
1248+
public override void OnPageHandlerExecuting(PageHandlerExecutingContext context)
1249+
{
1250+
base.OnPageHandlerExecuting(context);
1251+
}
1252+
1253+
public override void OnPageHandlerExecuted(PageHandlerExecutedContext context)
1254+
{
1255+
base.OnPageHandlerExecuted(context);
1256+
}
1257+
1258+
public override void OnPageHandlerSelected(PageHandlerSelectedContext context)
1259+
{
1260+
base.OnPageHandlerSelected(context);
1261+
}
1262+
}
1263+
12171264
private static DefaultPageApplicationModelProvider CreateProvider()
12181265
{
12191266
var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();

0 commit comments

Comments
 (0)