125 lines
5.0 KiB
C#
125 lines
5.0 KiB
C#
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<long>("FileSizeLimit");
|
|
|
|
// To save physical files to a path provided by configuration:
|
|
_targetFilePath = config.GetValue<string>("StoredFilesPath");
|
|
|
|
// To save physical files to the temporary files folder, use:
|
|
//_targetFilePath = Path.GetTempPath();
|
|
}
|
|
|
|
#region snippet_UploadPhysical 上传到服务器物理路径
|
|
|
|
|
|
[HttpPost]
|
|
[DisableFormValueModelBinding]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> 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
|
|
}
|
|
}
|