diff --git a/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs b/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs index 9f1f11c9fcef..5111852de439 100644 --- a/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs @@ -83,6 +83,7 @@ private static bool IsAllowedAttribute(object attribute) { return attribute is ProducesResponseTypeAttribute || attribute is ProducesDefaultResponseTypeAttribute || - attribute is ApiConventionNameMatchAttribute; + attribute is ApiConventionNameMatchAttribute || + attribute.GetType().FullName == "System.Runtime.CompilerServices.NullableContextAttribute"; } } diff --git a/src/Mvc/Mvc.Core/test/ApiConventionMethodAttributeTest.cs b/src/Mvc/Mvc.Core/test/ApiConventionMethodAttributeTest.cs index 45f8c5fc180a..fc3c19fa5e2f 100644 --- a/src/Mvc/Mvc.Core/test/ApiConventionMethodAttributeTest.cs +++ b/src/Mvc/Mvc.Core/test/ApiConventionMethodAttributeTest.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Mvc.ApiExplorer; @@ -46,6 +46,41 @@ public void Constructor_ThrowsIfTypeIsNotStatic() expected); } + public static class ConventionWithNullableContextAttribute + { +#nullable enable + public static void Get(Foo? foo) { } +#nullable restore + } + + public class Foo { } + + [Fact] + public void Convention_With_NullableContextAttribute_Has_NullableContextAttribute_On_Get_Method() + { + // Arrange + var type = typeof(ConventionWithNullableContextAttribute); + var method = type.GetMethod(nameof(ConventionWithNullableContextAttribute.Get)); + var attributes = method.GetCustomAttributes(false); + + // Act & Assert + Assert.Contains(attributes, (a) => + { + var attributeType = a.GetType(); + return attributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute"; + }); + } + + [Fact] + public void Convention_With_NullableContextAttribute_With_NullableContextAttribute_On_Get_Method_Does_Not_Throw() + { + // Arrange + var methodName = typeof(ConventionWithNullableContextAttribute).FullName + '.' + nameof(ConventionWithNullableContextAttribute.Get); + var attribute = typeof(ProducesAttribute); + + new ApiConventionMethodAttribute(typeof(ConventionWithNullableContextAttribute), nameof(ConventionWithNullableContextAttribute.Get)); + } + [Fact] public void Constructor_ThrowsIfMethodCannotBeFound() {