using System.IO; using System.Net; using System.Threading.Tasks; using IRaCIS.Core.API.Filter; using IRaCIS.Core.API.Utility; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Configuration; using Microsoft.Net.Http.Headers; namespace IRaCIS.Core.API.Controllers.Common { public class FileTestController : ControllerBase { private readonly string _targetFilePath; private readonly long _fileSizeLimit; private readonly string[] _permittedExtensions = { ".txt" ,".pdf"}; // Get the default form options so that we can use them to set the default // limits for request body data. private static readonly FormOptions _defaultFormOptions = new FormOptions(); public FileTestController(IConfiguration config) { _fileSizeLimit = config.GetValue("FileSizeLimit"); // To save physical files to a path provided by configuration: _targetFilePath = config.GetValue("StoredFilesPath"); // To save physical files to the temporary files folder, use: //_targetFilePath = Path.GetTempPath(); } #region snippet_UploadPhysical 上传到服务器物理路径 [HttpPost] [DisableFormValueModelBinding] [ValidateAntiForgeryToken] public async Task UploadPhysical() { if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) { ModelState.AddModelError("File", $"The request couldn't be processed (Error 1)."); // Log error return BadRequest(ModelState); } var boundary = MultipartRequestHelper.GetBoundary( MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit); var reader = new MultipartReader(boundary, HttpContext.Request.Body); var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse( section.ContentDisposition, out var contentDisposition); if (hasContentDispositionHeader) { // This check assumes that there's a file // present without form data. If form data // is present, this method immediately fails // and returns the model error. if (!MultipartRequestHelper .HasFileContentDisposition(contentDisposition)) { ModelState.AddModelError("File", $"The request couldn't be processed (Error 2)."); // Log error return BadRequest(ModelState); } else { // Don't trust the file name sent by the client. To display // the file name, HTML-encode the value. var trustedFileNameForDisplay = WebUtility.HtmlEncode( contentDisposition.FileName.Value); var trustedFileNameForFileStorage = Path.GetRandomFileName(); // **WARNING!** // In the following example, the file is saved without // scanning the file's contents. In most production // scenarios, an anti-virus/anti-malware scanner API // is used on the file before making the file available // for download or for use by other systems. // For more information, see the topic that accompanies // this sample. var streamedFileContent = await FileHelpers.ProcessStreamedFile( section, contentDisposition, ModelState, _permittedExtensions, _fileSizeLimit); if (!ModelState.IsValid) { return BadRequest(ModelState); } using (var targetStream = System.IO.File.Create( Path.Combine(_targetFilePath, trustedFileNameForFileStorage))) { await targetStream.WriteAsync(streamedFileContent); } } } // Drain any remaining section body that hasn't been consumed and // read the headers for the next section. section = await reader.ReadNextSectionAsync(); } return Created(nameof(FileTestController), null); } #endregion } }