[Fixes #3915] Update FormFileModelBinder to avoid re-parsing the ContentDisposition header
This commit is contained in:
parent
477e620a6b
commit
1a87f6d91a
|
|
@ -102,19 +102,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||||
|
|
||||||
foreach (var file in form.Files)
|
foreach (var file in form.Files)
|
||||||
{
|
{
|
||||||
ContentDispositionHeaderValue parsedContentDisposition;
|
|
||||||
ContentDispositionHeaderValue.TryParse(file.ContentDisposition, out parsedContentDisposition);
|
|
||||||
|
|
||||||
// If there is an <input type="file" ... /> in the form and is left blank.
|
// If there is an <input type="file" ... /> in the form and is left blank.
|
||||||
if (parsedContentDisposition == null ||
|
if (file.Length == 0 && string.IsNullOrEmpty(file.FileName))
|
||||||
(file.Length == 0 &&
|
|
||||||
string.IsNullOrEmpty(HeaderUtilities.RemoveQuotes(parsedContentDisposition.FileName))))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileName = HeaderUtilities.RemoveQuotes(parsedContentDisposition.Name);
|
if (file.Name.Equals(modelName, StringComparison.OrdinalIgnoreCase))
|
||||||
if (fileName.Equals(modelName, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
postedFiles.Add(file);
|
postedFiles.Add(file);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,26 +66,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||||
Assert.Equal(2, files.Count);
|
Assert.Equal(2, files.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task FormFileModelBinder_FilesWithQuotedContentDisposition_BindSuccessful()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var formFiles = new FormFileCollection();
|
|
||||||
formFiles.Add(GetMockFormFileWithQuotedContentDisposition("file", "file1.txt"));
|
|
||||||
formFiles.Add(GetMockFormFileWithQuotedContentDisposition("file", "file2.txt"));
|
|
||||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
|
||||||
var bindingContext = GetBindingContext(typeof(IEnumerable<IFormFile>), httpContext);
|
|
||||||
var binder = new FormFileModelBinder();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = await binder.BindModelResultAsync(bindingContext);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.NotEqual(default(ModelBindingResult), result);
|
|
||||||
var files = Assert.IsAssignableFrom<IList<IFormFile>>(result.Model);
|
|
||||||
Assert.Equal(2, files.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FormFileModelBinder_ExpectSingleFile_BindFirstFile()
|
public async Task FormFileModelBinder_ExpectSingleFile_BindFirstFile()
|
||||||
{
|
{
|
||||||
|
|
@ -103,8 +83,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotEqual(default(ModelBindingResult), result);
|
Assert.NotEqual(default(ModelBindingResult), result);
|
||||||
var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
|
var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
|
||||||
Assert.Equal("form-data; name=file; filename=file1.txt",
|
Assert.Equal("file1.txt", file.FileName);
|
||||||
file.ContentDisposition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -168,9 +147,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||||
Assert.True(result.IsModelSet);
|
Assert.True(result.IsModelSet);
|
||||||
var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
|
var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
|
||||||
|
|
||||||
ContentDispositionHeaderValue contentDisposition;
|
Assert.Equal(expected, file.Name);
|
||||||
ContentDispositionHeaderValue.TryParse(file.ContentDisposition, out contentDisposition);
|
|
||||||
Assert.Equal(expected, contentDisposition.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -251,16 +228,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||||
private static IFormFile GetMockFormFile(string modelName, string filename)
|
private static IFormFile GetMockFormFile(string modelName, string filename)
|
||||||
{
|
{
|
||||||
var formFile = new Mock<IFormFile>();
|
var formFile = new Mock<IFormFile>();
|
||||||
formFile.Setup(f => f.ContentDisposition)
|
formFile.Setup(f => f.Name).Returns(modelName);
|
||||||
.Returns(string.Format("form-data; name={0}; filename={1}", modelName, filename));
|
formFile.Setup(f => f.FileName).Returns(filename);
|
||||||
return formFile.Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IFormFile GetMockFormFileWithQuotedContentDisposition(string modelName, string filename)
|
|
||||||
{
|
|
||||||
var formFile = new Mock<IFormFile>();
|
|
||||||
formFile.Setup(f => f.ContentDisposition)
|
|
||||||
.Returns(string.Format("form-data; name=\"{0}\"; filename=\"{1}\"", modelName, filename));
|
|
||||||
return formFile.Object;
|
return formFile.Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue