Skip to content

Commit 74461db

Browse files
committed
Fix handling of nullable types in validations generator
1 parent 0862db9 commit 74461db

File tree

3 files changed

+10
-7
lines changed

3 files changed

+10
-7
lines changed

src/Http/Http.Extensions/gen/Microsoft.AspNetCore.Http.ValidationsGenerator/Extensions/ITypeSymbolExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ public static ITypeSymbol UnwrapType(this ITypeSymbol type, INamedTypeSymbol enu
4646

4747
if (type.NullableAnnotation == NullableAnnotation.Annotated)
4848
{
49-
// Extract the underlying type from a reference type
50-
type = type.OriginalDefinition;
49+
// Remove the nullable annotation but keep any generic arguments, e.g. List<int>? → List<int>
50+
// so we can retain them in future steps.
51+
type = type.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
5152
}
5253

5354
if (type is INamedTypeSymbol namedType && namedType.IsEnumerable(enumerable) && namedType.TypeArguments.Length == 1)

src/Http/Http.Extensions/gen/Microsoft.AspNetCore.Http.ValidationsGenerator/Parsers/ValidationsGenerator.TypesParser.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ internal ImmutableArray<ValidatableType> ExtractValidatableTypes(IInvocationOper
2929
List<ITypeSymbol> visitedTypes = [];
3030
foreach (var parameter in parameters)
3131
{
32-
_ = TryExtractValidatableType(parameter.Type.UnwrapType(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_Collections_IEnumerable)), wellKnownTypes, ref validatableTypes, ref visitedTypes);
32+
_ = TryExtractValidatableType(parameter.Type, wellKnownTypes, ref validatableTypes, ref visitedTypes);
3333
}
3434
return [.. validatableTypes];
3535
}
3636

37-
internal bool TryExtractValidatableType(ITypeSymbol typeSymbol, WellKnownTypes wellKnownTypes, ref HashSet<ValidatableType> validatableTypes, ref List<ITypeSymbol> visitedTypes)
37+
internal bool TryExtractValidatableType(ITypeSymbol incomingTypeSymbol, WellKnownTypes wellKnownTypes, ref HashSet<ValidatableType> validatableTypes, ref List<ITypeSymbol> visitedTypes)
3838
{
39+
var typeSymbol = incomingTypeSymbol.UnwrapType(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_Collections_IEnumerable));
3940
if (typeSymbol.SpecialType != SpecialType.None)
4041
{
4142
return false;
@@ -126,7 +127,7 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
126127
// Check if the property's type is validatable, this resolves
127128
// validatable types in the inheritance hierarchy
128129
var hasValidatableType = TryExtractValidatableType(
129-
correspondingProperty.Type.UnwrapType(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_Collections_IEnumerable)),
130+
correspondingProperty.Type,
130131
wellKnownTypes,
131132
ref validatableTypes,
132133
ref visitedTypes);
@@ -153,7 +154,7 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
153154
continue;
154155
}
155156

156-
var hasValidatableType = TryExtractValidatableType(member.Type.UnwrapType(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_Collections_IEnumerable)), wellKnownTypes, ref validatableTypes, ref visitedTypes);
157+
var hasValidatableType = TryExtractValidatableType(member.Type, wellKnownTypes, ref validatableTypes, ref visitedTypes);
157158
var attributes = ExtractValidationAttributes(member, wellKnownTypes, out var isRequired);
158159

159160
// If the member has no validation attributes or validatable types and is not required, skip it.

src/Http/Http.Extensions/test/ValidationsGenerator/ValidationsGenerator.ComplexType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public class ComplexType
4545
4646
public SubTypeWithInheritance PropertyWithInheritance { get; set; } = new SubTypeWithInheritance("some-value", default);
4747
48-
public List<SubType> ListOfSubTypes { get; set; } = [];
48+
// Nullable to validate https://github.com/dotnet/aspnetcore/issues/61737
49+
public List<SubType>? ListOfSubTypes { get; set; } = [];
4950
5051
[DerivedValidation(ErrorMessage = "Value must be an even number")]
5152
public int IntegerWithDerivedValidationAttribute { get; set; }

0 commit comments

Comments
 (0)