
using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; using System; using System.Collections.Generic; using System.IO.Compression; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using YuYunAbp.Core.Km; using YuYunAbp.Application.Dtos; using Microsoft.AspNetCore.Mvc.ModelBinding; using YuYunAbp.Core.Km.Extensions; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc; namespace YuYunAbp.Application.Authorization { public class CustomFileUploadDtoBinder : IModelBinder { public async Task BindModelAsync(ModelBindingContext bindingContext) { if (IsMultipartRequest(bindingContext.HttpContext.Request)) { // 使用默认绑定 var model = new FileUpLoadDto(); var form = bindingContext.HttpContext.Request.Form; model.useHeaderRow = Convert.ToBoolean(form["useHeaderRow"]); model.FileType = (UploadContentType)Convert.ToInt32(form["FileType"]); var files = form.Files; var processedFiles = await ProcessFilesAsync(files); model.uploadedFile = processedFiles.FirstOrDefault(); bindingContext.Result = ModelBindingResult.Success(model); } } private async Task<IFormFileCollection> ProcessFilesAsync(IFormFileCollection files) { var processedFiles = new FormFileCollection(); foreach (var file in files) { if (IsZipFile(file)) { var unzippedFiles = await UnzipFilesAsync(file); foreach (var unzippedFile in unzippedFiles) { processedFiles.Add(unzippedFile); } } else { processedFiles.Add(file); } } return processedFiles; } private bool IsMultipartRequest(HttpRequest request) { return !string.IsNullOrEmpty(request.ContentType) && request.ContentType.Contains("multipart/form-data"); } private bool IsZipFile(IFormFile file) { return file.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) || file.ContentType == "application/zip" || file.ContentType == "application/x-zip-compressed"; } private async Task<List<IFormFile>> UnzipFilesAsync(IFormFile zipFile) { var extractedFiles = new List<IFormFile>(); var tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tempDirectory); try { using (var zipStream = zipFile.OpenReadStream()) using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read, false, Encoding.GetEncoding("GB2312"))) { foreach (var entry in archive.Entries) { if (string.IsNullOrEmpty(entry.Name)) continue; var safeFileName = Path.GetFileName(entry.Name); var ext = Path.GetExtension(entry.Name); var filePath = Path.Combine(tempDirectory, safeFileName); entry.ExtractToFile(filePath, overwrite: true); var fileInfo = new FileInfo(filePath); var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); extractedFiles.Add(new FormFile( fileStream, 0, fileInfo.Length, entry.Name, entry.Name) { Headers = new HeaderDictionary { [HeaderNames.ContentType] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } }); } } } finally { // 注意:不能立即删除目录,否则文件流还在使用 // Directory.Delete(tempDirectory, recursive: true); } return extractedFiles; } } [AttributeUsage(AttributeTargets.Parameter)] public class CustomModelBinderAttribute : ModelBinderAttribute { public CustomModelBinderAttribute() : base(typeof(CustomFileUploadDtoBinder)) { } } }
浙公网安备 33010602011771号