前言

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

1. 实现自定义绑定模型
  • 1.1 在 Asp.Net Core MVC 中,内置了很多种绑定模型,让我们可以很方便的去使用,比如下面常用的几种绑定模型
 FromBodyAttribute
FromFromAttribute
FromQueryAttribute
FromHeaderAttribute
FromServicesAttribute
FromRouteAttribute
  • 常见用法比如
    [HttpPost]
public async Task<IActionResult> PostInfo([FromBody]UserInfo user,[FromQuery] string city)
{
...
}
    1. 查看以上绑定模型,唯独缺少一个 FromFileAttribute ,下面就来实现一个自己的 FromFileAttribute
    public class FromFileAttribute : Attribute, IBindingSourceMetadata
{
public BindingSource BindingSource => BindingSource.FormFile;
}
  • 非常简单,就三行代码,完全照抄系统内置的绑定模型,唯一不同的就是指定 BindingSource 为 BindingSource.FormFile。
2. 实现一个上传文件实体类,专门用于接收客户端参数
  • 2.1 创建 UserFile
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.file.FileName;
}
}
} public async Task<string> 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. 上传文件
  • 3.1 下面就定义一个简单的 API 接口,用于测试上传文件
        [HttpPost]
public async Task<IActionResult> 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 操作

4. 上传测试
  • 4.1 现在通过控制台启动服务

  • 4.2 使用 Postman 模拟表单上传文件

  • 4.3 上传成功,现在来查看目录下是否有文件

结语
  • 在上传表单中,我们定义了附件的名称为 file 对应绑定模型的公共属性 File,这样模型就可以自动获得该文件
  • 表单中还传递了另外一个字段 filename,对应绑定模型的公共属性 FileName,实现自定义文件友好显示名称
  • 通过自定义模型绑定,实现了快速上传文件功能,该功能只能用于上传小文件,对于大文件,还是需要实现分片上传,或者使用 CDN 等服务商的接口
示例代码下载

(经 海阔天空XM. 提醒,由于上传了编译后的 dll 引起部分朋友杀毒软件误报,现已重新上传,感谢!)

https://github.com/lianggx/EasyAspNetCoreDemo/tree/master/Ron.UploadFile

Asp.Net Core 轻松学-一行代码搞定文件上传的更多相关文章

  1. Asp.Net Core 轻松学-一行代码搞定文件上传 JSONHelper

    Asp.Net Core 轻松学-一行代码搞定文件上传   前言     在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建 ...

  2. 【自动化专题】selenium如何轻松搞定文件上传

    使用selenium做自动化时,我们经常会遇到的一个让人头疼的问题就是文件上传. 问题的难点在于selenium无法识别并操作Windows窗口,若我们可以绕过弹出框直接把文件信息上传给选择按钮,难点 ...

  3. Asp.Net Core 轻松学系列-1阅读指引目录

    https://www.cnblogs.com/viter/p/10474091.html 目录 前言 1. 从安装到配置 2. 业务实现 3. 日志 4. 测试 5. 缓存使用 6.网络和通讯 7. ...

  4. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  5. Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

    前言 在上一篇文章中(Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库)[https://www.cnblogs.com/viter/p/10243577.html],介 ...

  6. Asp.Net Core 轻松学-多线程之Task(补充)

    前言     在上一章 Asp.Net Core 轻松学-多线程之Task快速上手 文章中,介绍了使用Task的各种常用场景,但是感觉有部分内容还没有完善,在这里补充一下. 1. 任务的等待 在使用 ...

  7. Asp.Net Core 轻松学-利用文件监视进行快速测试开发

    前言     在进行 Asp.Net Core 应用程序开发过程中,通常的做法是先把业务代码开发完成,然后建立单元测试,最后进入本地系统集成测试:在这个过程中,程序员的大部分时间几乎都花费在开发.运行 ...

  8. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  9. C# 中一些类关系的判定方法 C#中关于增强类功能的几种方式 Asp.Net Core 轻松学-多线程之取消令牌

    1.  IsAssignableFrom实例方法 判断一个类或者接口是否继承自另一个指定的类或者接口. public interface IAnimal { } public interface ID ...

随机推荐

  1. BZOJ_3894_文理分科&&BZOJ_2127_happiness_最小割

    BZOJ_3894_文理分科_最小割 Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进 ...

  2. LVS+keepalived负载均衡

    背景:         随着你的网站业务量的增长你网站的服务器压力越来越大?需要负载均衡方案!商业的硬件如F5又太贵,你们又是创业型互联公司如何有效节约成本,节省不必要的浪费?同时实现商业硬件一样的高 ...

  3. Django中Middleware中间件

    Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法.实际上当 ...

  4. 【毕业】-《伯恩茅斯大学毕业证书》BU一模一样原件

    ☞伯恩茅斯大学毕业证书[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归 ...

  5. java创建线程的几种方式,了解一下

    1.继承Thread,重写run()  public class MyThread extends Thread{ @Override public void run() { System.out.p ...

  6. 关于DatePicker在模态窗体下失效的问题

    最近用bootstrap做了一个租赁相关的管理系统,由于前端知识薄弱,也是编查资料边做.关于一些控件的用法,也是从网上查资料.下面,来说一下在写前端页面时遇到的几个坑. 这个系统中,日期控件用的是Da ...

  7. Android 7.0 启动篇 — init原理(二)(转 Android 9.0 分析)

    ========================================================          ================================== ...

  8. JS 图片放大镜

    今天练习一个小demo, 从本地读取图片, 然后实现类似淘宝放大镜的效果, 再加两个需求 1 .可以调节缩放比例,默认放大两倍 2 . 图片宽高自适应, 不固定宽高 话不多说先看效果: 原理:1, 右 ...

  9. 性能测试入门 — LoadRunner 使用初探

    前言: 性能测试是利用产品.人员和流程来降低应用程序.升级程序或补丁程序部署风险的一种手段.性能测试的主要思想是通过模拟产生真实业务的压力对被测系统进行加压,验证被测系统在不同压力情况下的表现,找出其 ...

  10. 无敌简单快速的文件服务器sgfs

    前言 想要构建一个Linux文件服务器?看看下面几个要求是不是你想要的? 1.只需要单节点部署就够了 2.部署启动简单,下载之后,一键启动,一键关闭 3.不需要任何其他的依赖安装,而且运行时占用内存资 ...