[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var formValueProviderFactory = context.ValueProviderFactories
.OfType<FormValueProviderFactory>()
.FirstOrDefault();
if (formValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(formValueProviderFactory);
}
//下面这段不要忘了,对于asp.net core 6.0及以后版本,网上很多都没有这段。
var formFileValueProviderFactory = context.ValueProviderFactories
.OfType<FormFileValueProviderFactory>()
.FirstOrDefault();
if (formFileValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(formFileValueProviderFactory);
}
var jqueryFormValueProviderFactory = context.ValueProviderFactories
.OfType<JQueryFormValueProviderFactory>()
.FirstOrDefault();
if (jqueryFormValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(jqueryFormValueProviderFactory);
}
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
[HttpPost("dbrestore")]
[RequestSizeLimit(3L * 1024L * 1024L * 1024L)] //设置允许最大的文件大小为3G
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadLargeFile([FromServices] IHttpContextAccessor httpContextAccessor)
{
var request = httpContextAccessor.HttpContext.Request;
// validation of Content-Type
// 1. first, it must be a form-data request
// 2. a boundary should be found in the Content-Type
if (!request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
{
return new UnsupportedMediaTypeResult();
}
var boundary = HeaderUtilities.RemoveQuotes(mediaTypeHeader.Boundary.Value).Value;
var reader = new MultipartReader(boundary, request.Body);
var section = await reader.ReadNextSectionAsync();
// This sample try to get the first file from request and save it
// Make changes according to your needs in actual use
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
out var contentDisposition);
if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
!string.IsNullOrEmpty(contentDisposition.FileName.Value))
{
// Don't trust any file name, file extension, and file data from the request unless you trust them completely
// Otherwise, it is very likely to cause problems such as virus uploading, disk filling, etc
// In short, it is necessary to restrict and verify the upload
// Here, we just use the temporary folder and a random file name
// Get the temporary folder, and combine a random file name with it
var fileName = Path.GetRandomFileName();
var saveToPath = Path.Combine(Path.GetTempPath(), fileName);
using (var targetStream = sysio.File.Create(saveToPath))
{
await section.Body.CopyToAsync(targetStream);
}
return new OkResult();
}
section = await reader.ReadNextSectionAsync();
}
// If the code runs to this location, it means that no files have been saved
return new BadRequestObjectResult("No files data in the request.");
}
参考:
https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/mvc/models/file-uploads/samples/5.x/LargeFilesSample/Controllers/FileUploadController.cs
https://stackoverflow.com/questions/62502286/uploading-and-downloading-large-files-in-asp-net-core-3-1