diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/DisallowNonParsableComplexTypesOnParameters.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/DisallowNonParsableComplexTypesOnParameters.cs index 22ef6d3bdd38..3415579ff0aa 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/DisallowNonParsableComplexTypesOnParameters.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/DisallowNonParsableComplexTypesOnParameters.cs @@ -129,7 +129,7 @@ static bool ReportFromAttributeDiagnostic(OperationAnalysisContext context, Well // If it is nullable and we have type arguments, unwrap it. // The length check aims to alleviate AD0001 warnings when referencing methods in external class libraries that contain parameters - if (parameterTypeSymbol!.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T && + if (parameterTypeSymbol?.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T && parameterTypeSymbol.TypeArguments.Length > 0) { parameterTypeSymbol = parameterTypeSymbol.TypeArguments[0] as INamedTypeSymbol; diff --git a/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DisallowNonParsableComplexTypesOnParametersTest.cs b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DisallowNonParsableComplexTypesOnParametersTest.cs index 58e7476ca796..819eea5fd2da 100644 --- a/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DisallowNonParsableComplexTypesOnParametersTest.cs +++ b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DisallowNonParsableComplexTypesOnParametersTest.cs @@ -738,5 +738,28 @@ public class CommercialCustomer : ICustomer // Act await VerifyCS.VerifyAnalyzerAsync(source); } + + [Fact] + public async Task Handler_Parameter_WithGenericTypeParameter_Works() + { + // Arrange + var source = """ + using Microsoft.AspNetCore.Builder; + + var webApp = WebApplication.Create(); + + static void UseEndpoint(WebApplication app) where TEndpointInput : class + { + app.MapPost("/test", (TEndpointInput data) => { }); + } + + UseEndpoint(webApp); + + public class TestEndpointInput { } + """; + + // Act + await VerifyCS.VerifyAnalyzerAsync(source); + } } diff --git a/src/Framework/AspNetCoreAnalyzers/test/Verifiers/CSharpAnalyzerVerifier.cs b/src/Framework/AspNetCoreAnalyzers/test/Verifiers/CSharpAnalyzerVerifier.cs index cfbc023573b3..d146f8b471be 100644 --- a/src/Framework/AspNetCoreAnalyzers/test/Verifiers/CSharpAnalyzerVerifier.cs +++ b/src/Framework/AspNetCoreAnalyzers/test/Verifiers/CSharpAnalyzerVerifier.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.InternalTesting; @@ -30,7 +31,7 @@ public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) => CSharpAnalyzerVerifier.Diagnostic(descriptor); /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) + public static async Task VerifyAnalyzerAsync([StringSyntax("C#-test")] string source, params DiagnosticResult[] expected) { var test = new CSharpAnalyzerTest {