diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/InferParameterBindingInfoConvention.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/InferParameterBindingInfoConvention.cs index 8861263faf..15721bd2fa 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/InferParameterBindingInfoConvention.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/InferParameterBindingInfoConvention.cs @@ -59,7 +59,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels internal void InferParameterBindingSources(ActionModel action) { - var inferredBindingSources = new BindingSource[action.Parameters.Count]; + if (SuppressInferBindingSourcesForParameters) + { + return; + } for (var i = 0; i < action.Parameters.Count; i++) { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/InferParameterBindingInfoConventionTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/InferParameterBindingInfoConventionTest.cs index 26da271e36..5f27a66df8 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/InferParameterBindingInfoConventionTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/InferParameterBindingInfoConventionTest.cs @@ -93,6 +93,71 @@ Environment.NewLine + "int b"; Assert.Equal(expected, ex.Message); } + [Fact] + public void InferParameterBindingSources_InfersSources() + { + // Arrange + var actionName = nameof(ParameterBindingController.ComplexTypeModelWithCancellationToken); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var convention = GetConvention(modelMetadataProvider); + var action = GetActionModel(typeof(ParameterBindingController), actionName, modelMetadataProvider); + + // Act + convention.InferParameterBindingSources(action); + + // Assert + Assert.Collection( + action.Parameters, + parameter => + { + Assert.Equal("model", parameter.Name); + + var bindingInfo = parameter.BindingInfo; + Assert.NotNull(bindingInfo); + Assert.Same(BindingSource.Body, bindingInfo.BindingSource); + }, + parameter => + { + Assert.Equal("cancellationToken", parameter.Name); + + var bindingInfo = parameter.BindingInfo; + Assert.NotNull(bindingInfo); + Assert.Equal(BindingSource.Special, bindingInfo.BindingSource); + }); + } + + [Fact] + public void InferParameterBindingSources_DoesNotInferSources_IfSuppressInferBindingSourcesForParametersIsSet() + { + // Arrange + var actionName = nameof(ParameterBindingController.ComplexTypeModelWithCancellationToken); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var convention = GetConvention(modelMetadataProvider); + var action = GetActionModel(typeof(ParameterBindingController), actionName, modelMetadataProvider); + + convention.SuppressInferBindingSourcesForParameters = true; + + // Act + convention.InferParameterBindingSources(action); + + // Assert + Assert.Collection( + action.Parameters, + parameter => + { + Assert.Equal("model", parameter.Name); + Assert.Null(parameter.BindingInfo); + }, + parameter => + { + Assert.Equal("cancellationToken", parameter.Name); + + var bindingInfo = parameter.BindingInfo; + Assert.NotNull(bindingInfo); + Assert.Equal(BindingSource.Special, bindingInfo.BindingSource); + }); + } + [Fact] public void Apply_PreservesBindingInfo_WhenInferringFor_ParameterWithModelBinder_AndExplicitName() {