当前位置: 代码迷 >> 综合 >> WebAPI 多文件批量上传,大文件上传,实现先验证文件再存磁盘
  详细解决方案

WebAPI 多文件批量上传,大文件上传,实现先验证文件再存磁盘

热度:98   发布时间:2023-12-10 17:49:45.0

研究了几天的 WebAPI 多文件批量上传功能,也终于找到了无法先验证再存盘的解决方法,以下是本次的测试代码,希望能对大家有帮助!~


  • 首先上服务端多文件接收的接口代码

    public class FileController : ServiceBase{////// 服务端文件上传接口///[Route("~/upload")][HttpPost, HttpGet]public async Task<string> Upload(){System.Diagnostics.Debugger.Launch(); //唤起调试器if (!Request.Content.IsMimeMultipartContent())return "缺少附件。";var savePath = $@"D:\ReceiveUpload\{DateTime.Now.ToString("yyyy-MM-dd")}";    //定义一个用于存储接收文件的目录//确保目录存在if (!Directory.Exists(savePath))Directory.CreateDirectory(savePath);//使用异步接收客户端上传的多个文件信息var multi = await Request.Content.ReadAsMultipartAsync();var fileCount = 0;//遍历全部文件foreach (var content in multi.Contents){var contentType = content.Headers.ContentType;                            //客户端定义的Content-Typevar name = content.Headers.ContentDisposition.Name;                       //客户端定义的Name参数var fileName = content.Headers.ContentDisposition.FileName?.Trim('"');    //客户端上传的文件名称var fileType = Path.GetExtension(fileName)?.TrimStart('.');               //获取文件扩展名if (string.IsNullOrWhiteSpace(fileName))continue;//非文件则跳过++fileCount;//获取文件流数据(根据自己需求2选1即可)var fileBytes = await content.ReadAsByteArrayAsync();var fileStream = await content.ReadAsStreamAsync();var fileLength = fileStream.Length;             //获取文件大小switch (fileType.ToLower()){case "jpg":case "png":#region 验证图片文件{var image = new Bitmap(fileStream); //获取图片信息var imgWidth = image.Width;         //获取图片宽度var imgHeight = image.Height;       //获取图片高度var imgLength = fileStream.Length;  //获取图片大小//PS:可在此处对图片大小与分辨率大小进行验证//将此图片保存到磁盘image.Save($@"{savePath}\{fileName}");//释放资源image.Dispose();}#endregionbreak;default://return $"不允许的文件格式“{fileType}”。";//将文件保存到磁盘中File.WriteAllBytes($@"{savePath}\{fileName}", fileBytes);break;}//释放资源fileStream.Dispose();}return $"已接收到{fileCount}个文件。";}}
  • 其次是客户端程序的文件上传代码

        /// <summary>/// 客户端批量上传文件/// </summary>[TestMethod]public void TestUpload(){var url = "http://127.0.0.1:8080/upload";var filesPath = new List<string>();{filesPath.Add(@"D:\测试文件\17,443KB (9088x3776).jpg");filesPath.Add(@"D:\测试文件\829KB.7z");filesPath.Add(@"D:\测试文件\107MB.zip");filesPath.Add(@"D:\测试文件\812MB.rar");}using (var client = new System.Net.Http.HttpClient())using (var content = new System.Net.Http.MultipartFormDataContent()){foreach (string filePath in filesPath)#region 添加文件{var fileName = filePath.Substring(filePath.LastIndexOf('\\') + 1);var fileBytes = File.ReadAllBytes(filePath);var fileContent = new System.Net.Http.ByteArrayContent(fileBytes);{//定义内容标头,使用 attachment 附件上传模式fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"){//定义一个Name参数 (非必填项,根据个人需求即可)Name = $"文件{++i}",//告诉服务端当前文件的名称FileName = fileName};}content.Add(fileContent);}#endregionvar responseMessage = client.PostAsync(url, content).Result;var status = responseMessage.StatusCode;var result = responseMessage.Content.ReadAsStringAsync().Result; //返回的页面内容//测试结果返回:"已接收到4个文件。"}}

  • 以上,如出现 Request 内容超过限制的长度异常,注意配置 Web.config

  <!--修改限制Request数据大小(单位:KB)--><system.web><httpRuntime targetFramework="4.6.1" maxRequestLength="4194304"/></system.web><!--修改限制Request数据大小(单位:Byte)--><system.webServer><security><requestFiltering><requestLimits maxAllowedContentLength="4294967295" /></requestFiltering></security></system.webServer>
  • 若上一步配置后还没能解决的,可再尝试修改 App_Start/WebApiConfig.cs

此处是在 https://www.cnblogs.com/dopeter/p/4675174.html 这篇文章中看到的,因实际测试时已通过上一步的配置 Web.config 已解决,所以还没能用上这段 ~ :-)

    public static class WebApiConfig{public static void Register(HttpConfiguration config){// 重写上传文件的内容存入内存的动作,为解决无法通过流上传大文件问题GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Hosting.IHostBufferPolicySelector), new NoBufferPolicySelector());}}/// <summary>/// 重写上传文件的内容存入内存的动作,为解决无法通过流上传大文件问题/// </summary>public class NoBufferPolicySelector : System.Web.Http.WebHost.WebHostBufferPolicySelector{public override bool UseBufferedInputStream(object hostContext){var context = hostContext as System.Web.HttpContextBase;if (context != null){if (context.Request.HttpMethod == System.Net.Http.HttpMethod.Post.ToString() && context.Request.ContentLength > 200000)return false;}return true;}}