diff --git a/src/Mvc/Mvc.Api.Analyzers/src/ActualApiResponseMetadataFactory.cs b/src/Mvc/Mvc.Api.Analyzers/src/ActualApiResponseMetadataFactory.cs index e0e2bed844f5..5524a957151f 100644 --- a/src/Mvc/Mvc.Api.Analyzers/src/ActualApiResponseMetadataFactory.cs +++ b/src/Mvc/Mvc.Api.Analyzers/src/ActualApiResponseMetadataFactory.cs @@ -74,15 +74,15 @@ void AnalyzeResponseExpression(IReturnOperation returnOperation) var statementReturnType = returnedValue.Type; - if (!symbolCache.IActionResult.IsAssignableFrom(statementReturnType)) + if (statementReturnType is not null && !symbolCache.IActionResult.IsAssignableFrom(statementReturnType)) { // Return expression is not an instance of IActionResult. Must be returning the "model". return new ActualApiResponseMetadata(returnOperation, statementReturnType); } var defaultStatusCodeAttribute = statementReturnType - .GetAttributes(defaultStatusCodeAttributeSymbol, inherit: true) - .FirstOrDefault(); + ?.GetAttributes(defaultStatusCodeAttributeSymbol, inherit: true) + ?.FirstOrDefault(); // If the type is not annotated with a default status code, then examine // the attributes on any invoked method returning the type. @@ -225,7 +225,7 @@ private static bool TryGetStatusCode( return false; } - internal static int? GetDefaultStatusCode(AttributeData attribute) + internal static int? GetDefaultStatusCode(AttributeData? attribute) { if (attribute != null && attribute.ConstructorArguments.Length == 1 && diff --git a/src/Mvc/Mvc.Api.Analyzers/test/ApiConventionAnalyzerIntegrationTest.cs b/src/Mvc/Mvc.Api.Analyzers/test/ApiConventionAnalyzerIntegrationTest.cs index caeefe7af91e..632f67e1da77 100644 --- a/src/Mvc/Mvc.Api.Analyzers/test/ApiConventionAnalyzerIntegrationTest.cs +++ b/src/Mvc/Mvc.Api.Analyzers/test/ApiConventionAnalyzerIntegrationTest.cs @@ -40,6 +40,10 @@ public Task NoDiagnosticsAreReturned_ForReturnStatementsInLambdas() public Task NoDiagnosticsAreReturned_ForReturnStatementsInLocalFunctions() => RunNoDiagnosticsAreReturned(); + [Fact] + public Task NoDiagnosticsAreReturned_ForApiController_WhenMethodNeverReturns() + => RunNoDiagnosticsAreReturned(); + [Fact] public async Task DiagnosticsAreReturned_ForIncompleteActionResults() { diff --git a/src/Mvc/Mvc.Api.Analyzers/test/TestFiles/ApiConventionAnalyzerIntegrationTest/NoDiagnosticsAreReturned_ForApiController_WhenMethodNeverReturns.cs b/src/Mvc/Mvc.Api.Analyzers/test/TestFiles/ApiConventionAnalyzerIntegrationTest/NoDiagnosticsAreReturned_ForApiController_WhenMethodNeverReturns.cs new file mode 100644 index 000000000000..900d178a5623 --- /dev/null +++ b/src/Mvc/Mvc.Api.Analyzers/test/TestFiles/ApiConventionAnalyzerIntegrationTest/NoDiagnosticsAreReturned_ForApiController_WhenMethodNeverReturns.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Mvc.Api.Analyzers; + +using System; + +[ApiController] +[Route("[controller]/[action]")] +public class NoDiagnosticsAreReturned_ForApiController_WhenMethodNeverReturns : ControllerBase +{ + public IActionResult GetItem() => throw new NotImplementedException(); +}