乘风原创程序

  • ASP.NET Core单文件和多文件上传并保存到服务端的方法
  • 2020/4/7 9:34:57
  • 前言:

      在我们日常开发中,关于图片,视频,音频,文档等相关文件上传并保存到服务端中是非常常见的一个功能,今天主要是把自己在开发中常用的两种方式记录下来方便一下直接使用,并且希望能够帮助到有需要的同学!

    一、配置ASP.NET Core中的静态文件:

    简单概述:

      在ASP.NET Core应用中静态资源文件需要进行相应的配置才能够提供给客户端直接使用。

    详情描述请参考官方文档:
    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/static-files?view=aspnetcore-3.1

    简单配置,提供 Web 根目录内的文件:

    调用 Startup.Configure中的UseStaticFiles 方法配置:

    public void Configure(IApplicationBuilder app)
    {
      app.UseStaticFiles();
    }
    

    二、文件服务器和应用程序配置(IIS,Kestrel):

    详情描述,请参考官方文档说明:
    https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1#server-and-app-configuration

    多部分正文长度限制:

    MultipartBodyLengthLimit 设置每个多部分正文的长度限制。 分析超出此限制的窗体部分时,会引发 InvalidDataException。 默认值为 134,217,728 (128 MB)。 使用 MultipartBodyLengthLimit 中的 Startup.ConfigureServices 设置自定义此限制:

    public void ConfigureServices(IServiceCollection services)
    {
      services.Configure<FormOptions>(options =>
      {
        // Set the limit to 256 MB
        options.MultipartBodyLengthLimit = 268435456;
      });
    }
    

    Kestrel 最大请求正文大小:

    对于 Kestrel 托管的应用,默认的最大请求正文大小为 30,000,000 个字节,约为 28.6 MB。 使用 MaxRequestBodySize Kestrel 服务器选项自定义限制:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
        .ConfigureKestrel((context, options) =>
        {
          // Handle requests up to 50 MB
          options.Limits.MaxRequestBodySize = 52428800;
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
          webBuilder.UseStartup<Startup>();
        });
    

    IIS 内容长度限制:

    默认的请求限制 (maxAllowedContentLength) 为 30,000,000 字节,大约 28.6 MB。 请在 web.config 文件中自定义此限制:

    <system.webServer>
     <security>
      <requestFiltering>
       <!-- Handle requests up to 50 MB -->
       <requestLimits maxAllowedContentLength="52428800" />
      </requestFiltering>
     </security>
    </system.webServer>

    三、单文件上传:

    using System;
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    
    namespace FileUploadManage.Controllers
    {
      /// <summary>
      /// 图片,视频,音频,文档等相关文件通用上传服务类
      /// </summary>
      public class FileUploadController : Controller
      {
        private static IHostingEnvironment _hostingEnvironment;
    
        public FileUploadController(IHostingEnvironment hostingEnvironment)
        {
          _hostingEnvironment = hostingEnvironment;
        }
    
        /// <summary>
        /// 单文件上传
        /// </summary>
        /// <returns></returns>
        public JsonResult SingleFileUpload()
        {
          var formFile = Request.Form.Files[0];//获取请求发送过来的文件
          var currentDate = DateTime.Now;
          var webRootPath = _hostingEnvironment.WebRootPath;//>>>相当于HttpContext.Current.Server.MapPath("") 
    
          try
          {
            var filePath = $"/UploadFile/{currentDate:yyyyMMdd}/";
    
            //创建每日存储文件夹
            if (!Directory.Exists(webRootPath + filePath))
            {
              Directory.CreateDirectory(webRootPath + filePath);
            }
    
            if (formFile != null)
            {
              //文件后缀
              var fileExtension = Path.GetExtension(formFile.FileName);//获取文件格式,拓展名
    
              //判断文件大小
              var fileSize = formFile.Length;
    
              if (fileSize > 1024 * 1024 * 10) //10M TODO:(1mb=1024X1024b)
              {
                return new JsonResult(new { isSuccess = false, resultMsg = "上传的文件不能大于10M" });
              }
    
              //保存的文件名称(以名称和保存时间命名)
              var saveName = formFile.FileName.Substring(0, formFile.FileName.LastIndexOf('.'))+"_"+currentDate.ToString("HHmmss")+ fileExtension;
    
              //文件保存
              using (var fs = System.IO.File.Create(webRootPath + filePath + saveName))
              {
                formFile.CopyTo(fs);
                fs.Flush();
              }
    
              //完整的文件路径
              var completeFilePath = Path.Combine(filePath, saveName);
    
              return new JsonResult(new { isSuccess = true, returnMsg = "上传成功", completeFilePath = completeFilePath });
            }
            else
            {
              return new JsonResult(new { isSuccess = false, resultMsg = "上传失败,未检测上传的文件信息~" });
            }
    
          }
          catch (Exception ex)
          {
            return new JsonResult(new { isSuccess = false, resultMsg = "文件保存失败,异常信息为:" + ex.Message });
          }
        }
    
      }
    }

    四、多文件上传:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore.Internal;
    
    namespace FileUploadManage.Controllers
    {
      /// <summary>
      /// 图片,视频,音频,文档等相关文件通用上传服务类
      /// </summary>
      public class FileUploadController : Controller
      {
        private static IHostingEnvironment _hostingEnvironment;
    
        public FileUploadController(IHostingEnvironment hostingEnvironment)
        {
          _hostingEnvironment = hostingEnvironment;
        }
    
        /// <summary>
        /// 多文件上传
        /// </summary>
        /// <param name="formCollection">表单集合值</param>
        /// <returns>服务器存储的文件信息</returns>
    
        public JsonResult MultiFileUpload(IFormCollection formCollection)
        {
          var currentDate = DateTime.Now;
          var webRootPath = _hostingEnvironment.WebRootPath;//>>>相当于HttpContext.Current.Server.MapPath("") 
          var uploadFileRequestList = new List<UploadFileRequest>();
          try
          {
            //FormCollection转化为FormFileCollection
            var files = (FormFileCollection)formCollection.Files;
    
            if (files.Any())
            {
              foreach (var file in files)
              {
                var uploadFileRequest = new UploadFileRequest();
    
                var filePath = $"/UploadFile/{currentDate:yyyyMMdd}/";
    
                //创建每日存储文件夹
                if (!Directory.Exists(webRootPath + filePath))
                {
                  Directory.CreateDirectory(webRootPath + filePath);
                }
    
                //文件后缀
                var fileExtension = Path.GetExtension(file.FileName);//获取文件格式,拓展名
    
                //判断文件大小
                var fileSize = file.Length;
    
                if (fileSize > 1024 * 1024 * 10) //10M TODO:(1mb=1024X1024b)
                {
                  continue;
                }
    
                //保存的文件名称(以名称和保存时间命名)
                var saveName = file.FileName.Substring(0, file.FileName.LastIndexOf('.')) + "_" + currentDate.ToString("HHmmss") + fileExtension;
    
                //文件保存
                using (var fs = System.IO.File.Create(webRootPath + filePath + saveName))
                {
                  file.CopyTo(fs);
                  fs.Flush();
                }
    
                //完整的文件路径
                var completeFilePath = Path.Combine(filePath, saveName);
    
                uploadFileRequestList.Add(new UploadFileRequest()
                {
                  FileName = saveName,
                  FilePath = completeFilePath
                });
              }
            }
            else
            {
              return new JsonResult(new { isSuccess = false, resultMsg = "上传失败,未检测上传的文件信息~" });
            }
          }
          catch (Exception ex)
          {
            return new JsonResult(new { isSuccess = false, resultMsg = "文件保存失败,异常信息为:" + ex.Message });
          }
    
          if (uploadFileRequestList.Any())
          {
            return new JsonResult(new { isSuccess = true, returnMsg = "上传成功", filePathArray = uploadFileRequestList });
          }
          else
          {
            return new JsonResult(new { isSuccess = false, resultMsg = "网络打瞌睡了,文件保存失败" });
          }
        }
    
      }
    
      /// <summary>
      /// 对文件上传响应模型
      /// </summary>
      public class UploadFileRequest
      {
        /// <summary>
        /// 文件名称
        /// </summary>
        public string FileName { get; set; }
    
        /// <summary>
        /// 文件路径
        /// </summary>
        public string FilePath { get; set; }
      }
    }