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

6 篇文章 0 订阅
3 篇文章 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-Type
                var 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();
                        }
                        #endregion
                        break;
                    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);
                }
                #endregion

                var 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;
        }
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值