Skip to content

Commit 49c653e

Browse files
committed
Infer BindingSource.FormFile for IEnumerable<IFormFile>
Fixes #7770
1 parent 077b1d8 commit 49c653e

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreMvcOptionsSetup.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ internal static void ConfigureAdditionalModelMetadataDetailsProviders(IList<IMet
9696
modelMetadataDetailsProviders.Add(new BindingSourceMetadataProvider(typeof(IFormFile), BindingSource.FormFile));
9797
modelMetadataDetailsProviders.Add(new BindingSourceMetadataProvider(typeof(IFormCollection), BindingSource.FormFile));
9898
modelMetadataDetailsProviders.Add(new BindingSourceMetadataProvider(typeof(IFormFileCollection), BindingSource.FormFile));
99+
modelMetadataDetailsProviders.Add(new BindingSourceMetadataProvider(typeof(IEnumerable<IFormFile>), BindingSource.FormFile));
99100

100101
// Add types to be excluded from Validation
101102
modelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Type)));

test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultApplicationModelProviderTest.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,52 @@ public void OnProvidersExecuting_AddsBindingSources_ForActionParameters_WithLega
211211
});
212212
}
213213

214+
[Fact]
215+
public void OnProvidersExecuting_InfersFormFileSourceForTypesAssignableFromIEnumerableOfFormFiles()
216+
{
217+
// Arrange
218+
var builder = new TestApplicationModelProvider(
219+
new MvcOptions { AllowValidatingTopLevelNodes = true },
220+
TestModelMetadataProvider.CreateDefaultProvider());
221+
var typeInfo = typeof(ModelBinderController).GetTypeInfo();
222+
223+
var context = new ApplicationModelProviderContext(new[] { typeInfo });
224+
225+
// Act
226+
builder.OnProvidersExecuting(context);
227+
228+
// Assert
229+
var controllerModel = Assert.Single(context.Result.Controllers);
230+
var action = Assert.Single(controllerModel.Actions, a => a.ActionMethod.Name == nameof(ModelBinderController.FormFilesSequences));
231+
Assert.Collection(
232+
action.Parameters,
233+
parameter =>
234+
{
235+
Assert.Equal("formFileEnumerable", parameter.ParameterName);
236+
Assert.Equal(BindingSource.FormFile, parameter.BindingInfo.BindingSource);
237+
},
238+
parameter =>
239+
{
240+
Assert.Equal("formFileCollection", parameter.ParameterName);
241+
Assert.Equal(BindingSource.FormFile, parameter.BindingInfo.BindingSource);
242+
},
243+
parameter =>
244+
{
245+
Assert.Equal("formFileIList", parameter.ParameterName);
246+
Assert.Equal(BindingSource.FormFile, parameter.BindingInfo.BindingSource);
247+
},
248+
parameter =>
249+
{
250+
Assert.Equal("formFileList", parameter.ParameterName);
251+
Assert.Equal(BindingSource.FormFile, parameter.BindingInfo.BindingSource);
252+
},
253+
parameter =>
254+
{
255+
Assert.Equal("formFileArray", parameter.ParameterName);
256+
Assert.Equal(BindingSource.FormFile, parameter.BindingInfo.BindingSource);
257+
});
258+
}
259+
214260
[Fact]
215261
public void OnProvidersExecuting_AddsBindingSources_ForActionParameters_ReadFromModelMetadata()
216262
{
@@ -1625,6 +1671,13 @@ public class ModelBinderController
16251671

16261672
public IActionResult PostAction([FromQuery] string fromQuery, IFormFileCollection formFileCollection, string unbound) => null;
16271673

1674+
public IActionResult FormFilesSequences(
1675+
IEnumerable<IFormFile> formFileEnumerable,
1676+
ICollection<IFormFile> formFileCollection,
1677+
IList<IFormFile> formFileIList,
1678+
List<IFormFile> formFileList,
1679+
IFormFile[] formFileArray) => null;
1680+
16281681
public IActionResult PostAction1(Guid guid) => null;
16291682

16301683
public IActionResult PostAction2([FromQuery] Guid fromQuery) => null;

test/Microsoft.AspNetCore.Mvc.Test/MvcOptionsSetupTest.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Diagnostics;
67
using System.IO;
78
using System.Linq;
@@ -189,6 +190,12 @@ public void Setup_SetsUpMetadataDetailsProviders()
189190
Assert.Equal(BindingSource.FormFile, formFileParameter.BindingSource);
190191
},
191192
provider =>
193+
{
194+
var formFileParameter = Assert.IsType<BindingSourceMetadataProvider>(provider);
195+
Assert.Equal(typeof(IEnumerable<IFormFile>), formFileParameter.Type);
196+
Assert.Equal(BindingSource.FormFile, formFileParameter.BindingSource);
197+
},
198+
provider =>
192199
{
193200
var excludeFilter = Assert.IsType<SuppressChildValidationMetadataProvider>(provider);
194201
Assert.Equal(typeof(Type), excludeFilter.Type);

0 commit comments

Comments
 (0)