From d3d6915ddff6eef9eef2c14c19bc60a46a7da242 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 18 Mar 2026 10:25:07 +0800 Subject: [PATCH] Address Copilot review: extract GetEffectiveMethodInfo helper and fix method resolution in ValidateActionArgumentsAsync Extract override method resolution logic into a reusable GetEffectiveMethodInfo helper to avoid duplication. Use the resolved override method in ValidateActionArgumentsAsync so that IMethodInvocationValidator validates against the concrete method on the controller type, not the base method from ActionDescriptor. Remove unused imports in FluentValidationTestAppService_Tests. --- .../Validation/AbpValidationActionFilter.cs | 40 +++++++++++-------- .../FluentValidationTestAppService_Tests.cs | 2 - 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs index ba2f0828cc..bcbeb2fa48 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; @@ -39,23 +40,13 @@ public class AbpValidationActionFilter : IAsyncActionFilter, IAbpFilter, ITransi return; } - if (context.ActionDescriptor.GetMethodInfo().DeclaringType != context.Controller.GetType()) + var effectiveMethod = GetEffectiveMethodInfo(context); + if (effectiveMethod != null) { - var baseMethod = context.ActionDescriptor.GetMethodInfo(); - - var overrideMethod = context.Controller.GetType().GetMethods().FirstOrDefault(x => - x.DeclaringType == context.Controller.GetType() && - x.Name == baseMethod.Name && - x.ReturnType == baseMethod.ReturnType && - x.GetParameters().Select(p => p.ToString()).SequenceEqual(baseMethod.GetParameters().Select(p => p.ToString()))); - - if (overrideMethod != null) + if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(effectiveMethod) != null) { - if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(overrideMethod) != null) - { - await next(); - return; - } + await next(); + return; } } @@ -69,9 +60,26 @@ public class AbpValidationActionFilter : IAsyncActionFilter, IAbpFilter, ITransi await next(); } + protected virtual MethodInfo? GetEffectiveMethodInfo(ActionExecutingContext context) + { + var baseMethod = context.ActionDescriptor.GetMethodInfo(); + if (baseMethod.DeclaringType == context.Controller.GetType()) + { + return null; + } + + return context.Controller.GetType().GetMethods().FirstOrDefault(x => + x.DeclaringType == context.Controller.GetType() && + x.Name == baseMethod.Name && + x.ReturnType == baseMethod.ReturnType && + x.GetParameters().Select(p => p.ToString()).SequenceEqual(baseMethod.GetParameters().Select(p => p.ToString()))); + } + protected virtual async Task ValidateActionArgumentsAsync(ActionExecutingContext context) { - var methodInfo = context.ActionDescriptor.GetMethodInfo(); + var baseMethod = context.ActionDescriptor.GetMethodInfo(); + var methodInfo = GetEffectiveMethodInfo(context) ?? baseMethod; + var parameterValues = methodInfo.GetParameters() .Select(p => context.ActionArguments.TryGetValue(p.Name!, out var value) ? value : null) .ToArray(); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/FluentValidationTestAppService_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/FluentValidationTestAppService_Tests.cs index b1d1f56ed5..563c68a039 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/FluentValidationTestAppService_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/FluentValidationTestAppService_Tests.cs @@ -1,10 +1,8 @@ -using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Shouldly; -using Volo.Abp.Http; using Xunit; namespace Volo.Abp.AspNetCore.Mvc.Validation;