本篇为大家介绍WebApi又一个必不可少的功能,那就是文件上传下载。
还记得我们在初期改造项目的时候删掉的wwwroot文件夹吗,这里放的就是项目中的静态资源文件,接下来我们来手动实现这个功能。
1、我们为项目添加一个静态的工具类,命名为CommonFun,并添加如下代码(以后你所有的静态扩展方法都可以放到这里)
using System.Text;
namespace NET6.Infrastructure.Tools
{
/// <summary>
/// 工具类
/// </summary>
public static class CommonFun
{
#region 文件操作
public static FileInfo[] GetFiles(string directoryPath)
{
if (!IsExistDirectory(directoryPath))
{
throw new DirectoryNotFoundException();
}
var root = new DirectoryInfo(directoryPath);
return root.GetFiles();
}
public static bool IsExistDirectory(string directoryPath)
{
return Directory.Exists(directoryPath);
}
public static string ReadFile(string Path)
{
string s;
if (!File.Exists(Path))
s = "不存在相应的目录";
else
{
var f2 = new StreamReader(Path, Encoding.Default);
s = f2.ReadToEnd();
f2.Close();
f2.Dispose();
}
return s;
}
public static void FileMove(string OrignFile, string NewFile)
{
File.Move(OrignFile, NewFile);
}
public static void CreateDir(string dir)
{
if (dir.Length == 0) return;
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
#endregion
}
}
2、打开Program.cs,添加如下代码
#region 启用静态资源访问
//创建目录
var path = Path.Combine(basePath, "Files/");
CommonFun.CreateDir(path);
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(path),
RequestPath = "/Files"
});
#endregion
至此我们就在项目中创建了Files文件夹,并且启用了静态文件访问功能。
3、接下来我们新建一个控制器,命名为UploadController,并添加如下代码
using Microsoft.AspNetCore.Mvc;
using NET6.Infrastructure.Tools;
namespace NET6.Api.Controllers
{
/// <summary>
/// 文件上传
/// </summary>
[Route("upload")]
public class UploadController : BaseController
{
readonly IConfiguration _config;
readonly IWebHostEnvironment _env;
public UploadController(IConfiguration config, IWebHostEnvironment env)
{
_config = config;
_env = env;
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="path">文件分类的文件夹名称</param>
/// <returns></returns>
[HttpPost("file")]
public async Task<IActionResult> FileUpload(string path = "default")
{
var files = Request.Form.Files;
if (files.Count == 0) return Ok(JsonView("请选择文件"));
var domain = _config["Domain"];
var dircstr = $"/Files/{path}/{DateTime.Now:yyyyMMdd}/";
var result = new List<string>();
foreach (var file in files)
{
var filename = Path.GetFileName(file.FileName);
if (filename.IsNull()) continue;
var fileext = Path.GetExtension(filename).ToLower();
var folderpath = _env.ContentRootPath;
CommonFun.CreateDir(folderpath + dircstr);
//重新命名文件
var pre = DateTime.Now.ToString("yyyyMMddHHmmssffff");
var after = CommonFun.GetRandom(1000, 9999).ToString();
var fileloadname = dircstr + pre + "_" + after + ProExt(fileext);
using (var stream = new FileStream(folderpath + fileloadname, FileMode.Create))
{
await file.CopyToAsync(stream);
}
result.Add(domain + fileloadname);
}
return Ok(JsonView(result));
}
#region 校验文件类型
string[] badext = { "exe", "msi", "bat", "com", "sys", "aspx", "asax", "ashx" };
private string ProExt(string ext)
{
if (ext.IsNull()) return "";
if (badext.Contains(ext)) throw new Exception("危险文件");
if (ext.First() == '.') return ext;
return "." + ext;
}
#endregion
}
}
至此,我们的文件上传功能便已经开发完成。
聪明的你会发现对于某些特殊文件会出现无法下载的情况,原因是特殊文件需要手动启用MIME支持。
4、我们打开Program.cs,改造一下代码,将我们需要的MIME类型添加到项目中
再次尝试发现文件已经可以正常下载。