using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; using wispro.sp.entity; using wispro.sp.share; namespace wispro.sp.api.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class AttachFilesController : ControllerBase { private readonly IWebHostEnvironment env; private readonly ILogger logger; private readonly spDbContext Context; public AttachFilesController(IWebHostEnvironment env, ILogger logger,spDbContext context) { this.env = env; this.logger = logger; this.Context = context; } private string GetContentType(string path) { var provider = new FileExtensionContentTypeProvider(); string contentType; if (!provider.TryGetContentType(path, out contentType)) { contentType = "application/octet-stream"; } return contentType; } [HttpGet,DisableRequestSizeLimit] public async Task Download(string Id) { var filename = Context.AttachFiles.Where(a => a.Id == new Guid(Id)).FirstOrDefault(); if (filename != null) { var attachfileSavePath = utility.ConfigHelper.GetSectionValue("AttachFileSavePath"); var filePath = Path.Combine(attachfileSavePath, filename.SavePath); var context = HttpContext; if (System.IO.File.Exists(filePath)) { var memory = new MemoryStream(); await using (var stream = new FileStream(filePath, FileMode.Open)) { await stream.CopyToAsync(memory); } memory.Position = 0; return File(memory, GetContentType(filename.Name), filename.Name); } else return NotFound(); } else { return NotFound(); } } public async Task Delete(string Id) { var filename = Context.AttachFiles.Where(a => a.Id == new Guid(Id)).FirstOrDefault(); if (filename != null) { var attachfileSavePath = utility.ConfigHelper.GetSectionValue("AttachFileSavePath"); var filePath = Path.Combine(attachfileSavePath, filename.SavePath); Context.AttachFiles.Remove(filename); await Context.SaveChangesAsync(); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); return true; } else { return false; } } else { return false; } } [HttpPost] public async Task> PostFile( [FromForm] IEnumerable files) { var maxAllowedFiles = 3; long maxFileSize = 1024 * 1024 * 15; var filesProcessed = 0; var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/"); List uploadResults = new(); foreach (var file in files) { var attachFile = new AttachFile(); string trustedFileNameForFileStorage; var untrustedFileName = file.FileName; attachFile.Name = untrustedFileName; Staff uploadUser = Context.Staffs.Where(s => s.Name == "何倚雯").FirstOrDefault(); if (uploadUser != null) { attachFile.UploadUserId = uploadUser.Id; } var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName); if (filesProcessed < maxAllowedFiles) { if (file.Length == 0) { logger.LogInformation("{FileName} length is 0 (Err: 1)", trustedFileNameForDisplay); //uploadResult.ErrorCode = 1; } else if (file.Length > maxFileSize) { logger.LogInformation("{FileName} of {Length} bytes is " + "larger than the limit of {Limit} bytes (Err: 2)", trustedFileNameForDisplay, file.Length, maxFileSize); //uploadResult.ErrorCode = 2; } else { try { trustedFileNameForFileStorage = Path.GetRandomFileName(); var attachfileSavePath = utility.ConfigHelper.GetSectionValue("AttachFileSavePath"); var path = Path.Combine(attachfileSavePath, trustedFileNameForFileStorage); await using FileStream fs = new(path, FileMode.Create); await file.CopyToAsync(fs); attachFile.SavePath = path; logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path); Context.AttachFiles.Add(attachFile); Context.SaveChanges(); //uploadResult.Uploaded = true; //uploadResult.StoredFileName = trustedFileNameForFileStorage; } catch (IOException ex) { logger.LogError("{FileName} error on upload (Err: 3): {Message}", trustedFileNameForDisplay, ex.Message); //uploadResult.ErrorCode = 3; } } filesProcessed++; } else { logger.LogInformation("{FileName} not uploaded because the " + "request exceeded the allowed {Count} of files (Err: 4)", trustedFileNameForDisplay, maxAllowedFiles); //uploadResult.ErrorCode = 4; } uploadResults.Add(attachFile); } return new CreatedResult(resourcePath, uploadResults); } } }