Skip to content

Commit 83c7bf0

Browse files
CopilotcaptainsafiaBrennanConroy
authored
Small improvements to reduce allocations in validation filter logic (#62056)
Co-authored-by: captainsafia <[email protected]> Co-authored-by: BrennanConroy <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]>
1 parent 9c8a0c3 commit 83c7bf0

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

src/Http/Routing/src/ValidationEndpointFilterFactory.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ namespace Microsoft.AspNetCore.Http.Validation;
1414

1515
internal static class ValidationEndpointFilterFactory
1616
{
17+
// A small struct to hold the validatable parameter details to avoid allocating arrays for parameters that don't need validation
18+
private readonly record struct ValidatableParameterEntry(int Index, IValidatableInfo Parameter, string DisplayName);
19+
1720
public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context, EndpointFilterDelegate next)
1821
{
1922
var parameters = context.MethodInfo.GetParameters();
@@ -25,12 +28,10 @@ public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context
2528

2629
var serviceProviderIsService = context.ApplicationServices.GetService<IServiceProviderIsService>();
2730

28-
var parameterCount = parameters.Length;
29-
var validatableParameters = new IValidatableInfo[parameterCount];
30-
var parameterDisplayNames = new string[parameterCount];
31-
var hasValidatableParameters = false;
31+
// Use a list to only store validatable parameters instead of arrays for all parameters
32+
List<ValidatableParameterEntry>? validatableParameters = null;
3233

33-
for (var i = 0; i < parameterCount; i++)
34+
for (var i = 0; i < parameters.Length; i++)
3435
{
3536
// Ignore parameters that are resolved from the DI container.
3637
if (IsServiceParameter(parameters[i], serviceProviderIsService))
@@ -40,13 +41,15 @@ public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context
4041

4142
if (options.TryGetValidatableParameterInfo(parameters[i], out var validatableParameter))
4243
{
43-
validatableParameters[i] = validatableParameter;
44-
parameterDisplayNames[i] = GetDisplayName(parameters[i]);
45-
hasValidatableParameters = true;
44+
validatableParameters ??= [];
45+
validatableParameters.Add(new ValidatableParameterEntry(
46+
i,
47+
validatableParameter,
48+
GetDisplayName(parameters[i])));
4649
}
4750
}
4851

49-
if (!hasValidatableParameters)
52+
if (validatableParameters is null || validatableParameters.Count == 0)
5053
{
5154
return next;
5255
}
@@ -55,18 +58,20 @@ public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context
5558
{
5659
ValidateContext? validateContext = null;
5760

58-
for (var i = 0; i < context.Arguments.Count; i++)
61+
foreach (var entry in validatableParameters)
5962
{
60-
var validatableParameter = validatableParameters[i];
61-
var displayName = parameterDisplayNames[i];
63+
if (entry.Index >= context.Arguments.Count)
64+
{
65+
break;
66+
}
6267

63-
var argument = context.Arguments[i];
64-
if (argument is null || validatableParameter is null)
68+
var argument = context.Arguments[entry.Index];
69+
if (argument is null)
6570
{
6671
continue;
6772
}
6873

69-
var validationContext = new ValidationContext(argument, displayName, context.HttpContext.RequestServices, items: null);
74+
var validationContext = new ValidationContext(argument, entry.DisplayName, context.HttpContext.RequestServices, items: null);
7075

7176
if (validateContext == null)
7277
{
@@ -81,7 +86,7 @@ public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context
8186
validateContext.ValidationContext = validationContext;
8287
}
8388

84-
await validatableParameter.ValidateAsync(argument, validateContext, context.HttpContext.RequestAborted);
89+
await entry.Parameter.ValidateAsync(argument, validateContext, context.HttpContext.RequestAborted);
8590
}
8691

8792
if (validateContext is { ValidationErrors.Count: > 0 })

0 commit comments

Comments
 (0)