Skip to content

Commit 044b6c5

Browse files
committed
Add SkipValidationAttribute to Microsoft.Extensions.Validation
1 parent c103a03 commit 044b6c5

9 files changed

+788
-4
lines changed

src/Shared/RoslynUtils/WellKnownTypeData.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ public enum WellKnownType
123123
System_ComponentModel_DataAnnotations_ValidationAttribute,
124124
System_ComponentModel_DataAnnotations_RequiredAttribute,
125125
System_ComponentModel_DataAnnotations_CustomValidationAttribute,
126+
Microsoft_Extensions_Validation_SkipValidationAttribute,
126127
System_Type,
127128
}
128129

@@ -244,6 +245,7 @@ public enum WellKnownType
244245
"System.ComponentModel.DataAnnotations.ValidationAttribute",
245246
"System.ComponentModel.DataAnnotations.RequiredAttribute",
246247
"System.ComponentModel.DataAnnotations.CustomValidationAttribute",
248+
"Microsoft.Extensions.Validation.SkipValidationAttribute",
247249
"System.Type",
248250
];
249251
}

src/Validation/gen/Parsers/ValidationsGenerator.TypesParser.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Immutable;
66
using System.Linq;
77
using Microsoft.AspNetCore.Analyzers.Infrastructure;
8+
using Microsoft.AspNetCore.Analyzers.RouteEmbeddedLanguage.Infrastructure;
89
using Microsoft.AspNetCore.App.Analyzers.Infrastructure;
910
using Microsoft.AspNetCore.Http.RequestDelegateGenerator.StaticRouteHandlerModel;
1011
using Microsoft.CodeAnalysis;
@@ -114,6 +115,8 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
114115
WellKnownTypeData.WellKnownType.Microsoft_AspNetCore_Http_Metadata_IFromServiceMetadata);
115116
var fromKeyedServiceAttributeSymbol = wellKnownTypes.Get(
116117
WellKnownTypeData.WellKnownType.Microsoft_Extensions_DependencyInjection_FromKeyedServicesAttribute);
118+
var skipValidationAttributeSymbol = wellKnownTypes.Get(
119+
WellKnownTypeData.WellKnownType.Microsoft_Extensions_Validation_SkipValidationAttribute);
117120

118121
// Special handling for record types to extract properties from
119122
// the primary constructor.
@@ -148,6 +151,12 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
148151
continue;
149152
}
150153

154+
// Skip parameter if it or its type are annotated with SkipValidationAttribute
155+
if (SymbolOrTypeHasAttribute(parameter, parameter.Type, skipValidationAttributeSymbol))
156+
{
157+
continue;
158+
}
159+
151160
// Check if the property's type is validatable, this resolves
152161
// validatable types in the inheritance hierarchy
153162
var hasValidatableType = TryExtractValidatableType(
@@ -186,6 +195,12 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
186195
continue;
187196
}
188197

198+
// Skip property if it or its type are annotated with SkipValidationAttribute
199+
if (SymbolOrTypeHasAttribute(member, member.Type, skipValidationAttributeSymbol))
200+
{
201+
continue;
202+
}
203+
189204
var hasValidatableType = TryExtractValidatableType(member.Type, wellKnownTypes, ref validatableTypes, ref visitedTypes);
190205
var attributes = ExtractValidationAttributes(member, wellKnownTypes, out var isRequired);
191206

@@ -228,4 +243,10 @@ internal static ImmutableArray<ValidationAttribute> ExtractValidationAttributes(
228243
NamedArguments: attribute.NamedArguments.ToDictionary(namedArgument => namedArgument.Key, namedArgument => namedArgument.Value.ToCSharpString()),
229244
IsCustomValidationAttribute: SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_CustomValidationAttribute))))];
230245
}
246+
247+
private static bool SymbolOrTypeHasAttribute(ISymbol symbol, ITypeSymbol typeSymbol, INamedTypeSymbol attributeSymbol)
248+
{
249+
return symbol.HasAttribute(attributeSymbol)
250+
|| typeSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, attributeSymbol));
251+
}
231252
}

src/Validation/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Microsoft.Extensions.Validation.IValidatableInfo.ValidateAsync(object? value, Mi
55
Microsoft.Extensions.Validation.IValidatableInfoResolver
66
Microsoft.Extensions.Validation.IValidatableInfoResolver.TryGetValidatableParameterInfo(System.Reflection.ParameterInfo! parameterInfo, out Microsoft.Extensions.Validation.IValidatableInfo? validatableInfo) -> bool
77
Microsoft.Extensions.Validation.IValidatableInfoResolver.TryGetValidatableTypeInfo(System.Type! type, out Microsoft.Extensions.Validation.IValidatableInfo? validatableInfo) -> bool
8+
Microsoft.Extensions.Validation.SkipValidationAttribute
9+
Microsoft.Extensions.Validation.SkipValidationAttribute.SkipValidationAttribute() -> void
810
Microsoft.Extensions.Validation.ValidatableParameterInfo
911
Microsoft.Extensions.Validation.ValidatableParameterInfo.ValidatableParameterInfo(System.Type! parameterType, string! name, string! displayName) -> void
1012
Microsoft.Extensions.Validation.ValidatablePropertyInfo
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Microsoft.Extensions.Validation;
5+
6+
/// <summary>
7+
/// Indicates that an object property should be skipped for validation.
8+
/// The generator will not generate validation code for this property and its type.
9+
/// </summary>
10+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)]
11+
public sealed class SkipValidationAttribute : Attribute
12+
{
13+
}

0 commit comments

Comments
 (0)