|
5 | 5 | using System.Collections.Immutable; |
6 | 6 | using System.Linq; |
7 | 7 | using Microsoft.AspNetCore.Analyzers.Infrastructure; |
| 8 | +using Microsoft.AspNetCore.Analyzers.RouteEmbeddedLanguage.Infrastructure; |
8 | 9 | using Microsoft.AspNetCore.App.Analyzers.Infrastructure; |
9 | 10 | using Microsoft.AspNetCore.Http.RequestDelegateGenerator.StaticRouteHandlerModel; |
10 | 11 | using Microsoft.CodeAnalysis; |
@@ -114,6 +115,8 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb |
114 | 115 | WellKnownTypeData.WellKnownType.Microsoft_AspNetCore_Http_Metadata_IFromServiceMetadata); |
115 | 116 | var fromKeyedServiceAttributeSymbol = wellKnownTypes.Get( |
116 | 117 | WellKnownTypeData.WellKnownType.Microsoft_Extensions_DependencyInjection_FromKeyedServicesAttribute); |
| 118 | + var skipValidationAttributeSymbol = wellKnownTypes.Get( |
| 119 | + WellKnownTypeData.WellKnownType.Microsoft_Extensions_Validation_SkipValidationAttribute); |
117 | 120 |
|
118 | 121 | // Special handling for record types to extract properties from |
119 | 122 | // the primary constructor. |
@@ -148,6 +151,12 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb |
148 | 151 | continue; |
149 | 152 | } |
150 | 153 |
|
| 154 | + // Skip parameter if it or its type are annotated with SkipValidationAttribute |
| 155 | + if (SymbolOrTypeHasAttribute(parameter, parameter.Type, skipValidationAttributeSymbol)) |
| 156 | + { |
| 157 | + continue; |
| 158 | + } |
| 159 | + |
151 | 160 | // Check if the property's type is validatable, this resolves |
152 | 161 | // validatable types in the inheritance hierarchy |
153 | 162 | var hasValidatableType = TryExtractValidatableType( |
@@ -186,6 +195,12 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb |
186 | 195 | continue; |
187 | 196 | } |
188 | 197 |
|
| 198 | + // Skip property if it or its type are annotated with SkipValidationAttribute |
| 199 | + if (SymbolOrTypeHasAttribute(member, member.Type, skipValidationAttributeSymbol)) |
| 200 | + { |
| 201 | + continue; |
| 202 | + } |
| 203 | + |
189 | 204 | var hasValidatableType = TryExtractValidatableType(member.Type, wellKnownTypes, ref validatableTypes, ref visitedTypes); |
190 | 205 | var attributes = ExtractValidationAttributes(member, wellKnownTypes, out var isRequired); |
191 | 206 |
|
@@ -228,4 +243,10 @@ internal static ImmutableArray<ValidationAttribute> ExtractValidationAttributes( |
228 | 243 | NamedArguments: attribute.NamedArguments.ToDictionary(namedArgument => namedArgument.Key, namedArgument => namedArgument.Value.ToCSharpString()), |
229 | 244 | IsCustomValidationAttribute: SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_CustomValidationAttribute))))]; |
230 | 245 | } |
| 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 | + } |
231 | 252 | } |
0 commit comments