-
Notifications
You must be signed in to change notification settings - Fork 25.3k
/
FileUploadController.cs
87 lines (75 loc) · 3.44 KB
/
FileUploadController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using System.IO;
using System.Threading.Tasks;
namespace LargeFilesSample.Controllers
{
/// <summary>
/// controller for upload large file
/// </summary>
[ApiController]
[Route("[controller]")]
public class FileUploadController : ControllerBase
{
private readonly ILogger<FileUploadController> _logger;
public FileUploadController(ILogger<FileUploadController> logger)
{
_logger = logger;
}
/// <summary>
/// Action for upload large file
/// </summary>
/// <remarks>
/// Request to this action will not trigger any model binding or model validation,
/// because this is a no-argument action
/// </remarks>
/// <returns></returns>
[HttpPost]
[Route(nameof(UploadLargeFile))]
public async Task<IActionResult> UploadLargeFile()
{
var request = 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 = System.IO.File.Create(saveToPath))
{
await section.Body.CopyToAsync(targetStream);
}
return Ok();
}
section = await reader.ReadNextSectionAsync();
}
// If the code runs to this location, it means that no files have been saved
return BadRequest("No files data in the request.");
}
}
}