.NET 6一行代码搞定文件上传

.NET 6一行代码搞定文件上传

在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能;通过创建自定义绑定模型来实现文件上传。

一、实现自定义绑定模型

1.1、 在 Asp.Net Core MVC 中,内置了很多种绑定模型,让我们可以很方便的去使用,比如下面常用的几种绑定模型

代码语言:javascript代码运行次数:0运行复制FromBodyAttribute

FromFromAttribute

FromQueryAttribute

FromHeaderAttribute

FromServicesAttribute

FromRouteAttribute

常见用法比如

代码语言:javascript代码运行次数:0运行复制[HttpPost]

public async Task PostInfo([FromBody]UserInfo user,[FromQuery] string city)

{

...

}

查看以上绑定模型,唯独缺少一个 FromFileAttribute ,下面就来实现一个自己的 FromFileAttribute

代码语言:javascript代码运行次数:0运行复制public class FromFileAttribute : Attribute, IBindingSourceMetadata

{

public BindingSource BindingSource => BindingSource.FormFile;

}

非常简单,就三行代码,完全照抄系统内置的绑定模型,唯一不同的就是指定 BindingSource 为 BindingSource.FormFile。

二、实现一个上传文件实体类,专门用于接收客户端参数

2.1 、创建 UserFile

代码语言:javascript代码运行次数:0运行复制public class UserFile

{

public string FileName { get; set; }

public long Length { get; set; }

public string Extension { get; set; }

public string FileType { get; set; }

private readonly static string[] Filters = { ".jpg", ".png", ".bmp" };

public bool IsValid => !string.IsNullOrEmpty(this.Extension) && Filters.Contains(this.Extension);

private IFormFile file;

public IFormFile File

{

get { return file; }

set

{

if (value != null)

{

this.file = value;

this.FileType = this.file.ContentType;

this.Length = this.file.Length;

this.Extension = this.file.FileName.Substring(file.FileName.LastIndexOf('.'));

if (string.IsNullOrEmpty(this.FileName))

this.FileName = this.FileName;

}

}

}

public async Task SaveAs(string destinationDir = null)

{

if (this.file == null)

throw new ArgumentNullException("没有需要保存的文件");

if (destinationDir != null)

Directory.CreateDirectory(destinationDir);

var newName = DateTime.Now.Ticks;

var newFile = Path.Combine(destinationDir ?? "", $"{newName}{this.Extension}");

using (FileStream fs = new FileStream(newFile, FileMode.CreateNew))

{

await this.file.CopyToAsync(fs);

fs.Flush();

}

return newFile;

}

}

UserFile 是一个带保持文件行为的实体类,该类的公共属性用于从表单域中接收和属性名称相同的表单值,其中公共属性 File 用于接收文件,并在设置值的时候去做一些其它属性初始化的工作,比如文件长度和扩展名、文件类型

其中还实现了一个简单的文件过滤器,判断客户端上传的文件是否属于服务端允许上传的文件扩展名

最后 SaveAs(string destinationDir = null) 通过传入指定目录,将文件保存,并返回保存后的文件绝对路径

三、上传文件

3.1、下面就定义一个简单的 API 接口,用于测试上传文件

代码语言:javascript代码运行次数:0运行复制[HttpPost]

public async Task Post([FromFile]UserFile file)

{

if (file == null || !file.IsValid)

return new JsonResult(new { code = 500, message = "不允许上传的文件类型" });

string newFile = string.Empty;

if (file != null)

{

newFile = await file.SaveAs("/data/files/images");

}

return new JsonResult(new { code = 0, message = "成功", url = newFile });

}

3.2、首先是在 Post([FromFile]UserFile file) 中使用上面创建的 FromFileAttribute 对模型 UserFile 进行绑定,然后验证文件是否正确,接下来通过 file.SaveAs("/data/files/images"); 保存文件

3.3 、上传代码非常简单,几乎到了无法精简的程度,最终发挥作用的就是 file.SaveAs 操作。

相关推荐

汽车加油加什么油
365彩票数据最专业

汽车加油加什么油

📅 07-01 👁️ 451
Edge如何设置自动刷新
365彩票数据最专业

Edge如何设置自动刷新

📅 07-02 👁️ 8189
正常男人能忍受多久无性婚姻(3
s365 2.2.3

正常男人能忍受多久无性婚姻(3

📅 07-01 👁️ 974
Edge如何设置自动刷新
365彩票数据最专业

Edge如何设置自动刷新

📅 07-02 👁️ 8189
英雄杀升50级最快的方法 英雄升15级需要多长时间,快速升级技巧分享
tips介入手术可以坚持几年
365账号限制投注怎么办

tips介入手术可以坚持几年

📅 07-04 👁️ 674
修改Tomcat的默认服务器端口号
s365 2.2.3

修改Tomcat的默认服务器端口号

📅 06-30 👁️ 4668
走吧,走吧,是什么歌?
s365 2.2.3

走吧,走吧,是什么歌?

📅 07-02 👁️ 2508
小猪吃奶的那些事儿
365彩票数据最专业

小猪吃奶的那些事儿

📅 06-29 👁️ 4035