.NET和.NET Core Web APi FormData多文件上传对比
前言
最近因维护.NET和.NET Core项目用到文件上传功能,虽说也做过,但是没做过什么对比,借此将二者利用Ajax通过FormData上传文件做一个总结,通过视图提交表单太简单,这里不做阐述,希望对有需要的童鞋能有力所能及的帮助。
.NET Web APi FormData文件上传
我们将参数和文件都通过FormData来上传,给出如下HTML代码
<div class="form-horizontal" style="margin-top:80px;">
<div class="form-group">
<label class="control-label col-md-2" for="caption">标题</label>
<div class="col-md-10">
<input name="title" id="title" type="text" />
</div>
</div> <div class="form-group">
<label class="control-label col-md-2" for="caption">文件</label>
<div class="col-md-10">
<input name="file" id="file" multiple type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="btn" value="提交" class="btn btn-success" />
</div>
</div>
</div>

恕我有点强迫症,界面好看点,看着也舒服,接下来则是脚本自然不用多说,利用FormData上传文件网上一搜遍地都是
$(function () {
$('#btn').click(function () {
var data = new FormData();
var title = $('#title').val();
data.append("title", title);
var files = $('#file')[0].files;;
for (var i = 0; i < files.length; i++) {
data.append("file", files[i]);
}
$.ajax({
url: '/api/upload/upload',
type: "post",
cache: false,
contentType: false,
processData: false,
data: data,
});
});
});
不过需要注意的是,对现代大多浏览器都都已支持将上述contentType设置为false后,就是在请求头中添加multipart/form-data,若是老版本浏览器则需要在请求头中手动添加表单多文件上传标识,如下
beforeSend: function (request) {
request.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary);
}
前端我们已经搞完,接下来我们回到后台,.NET Web APi已提供专门读取FormData数据的APi,如下:
//检查请求是否包含multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
} //将文件存储到App_Data文件夹下
var root = HttpContext.Current.Server.MapPath("~/App_Data"); //实例化MultipartFormDat流
var provider = new MultipartFormDataStreamProvider(root); // 读取表单数据
await Request.Content.ReadAsMultipartAsync(provider);
若上传2个文件,此时上传App_Data目录下的文件,如下这般

若要读取提交的表单参数,我们如下获取
//获取表单参数数据
var formData = provider.FormData;
那么我们怎么将上述类似临时文件数据转换为我们上传的文件数据呢?我们只需将上述文件名转换我们上传的文件名或者其他自定义文件名称即可,如下:
// 获取文件数据
foreach (MultipartFileData file in provider.FileData)
{
string fileName = file.Headers.ContentDisposition.FileName; if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(@"/") || fileName.Contains(@"\"))
{
fileName = Path.GetFileName(fileName);
} //将本地文件转换为实际所需文件
File.Move(file.LocalFileName, Path.Combine(root, fileName));
}

完美解决问题,当然除了通过上述流读取表单相关数据外,.NET Web APi还提供了内存表单流,只是利用此流时,表单参数和文件放置在一起,我们需要通过文件相关参数来做区分,然后分别获取文件和表单参数,如下:
var provider = new MultipartMemoryStreamProvider(); await Request.Content.ReadAsMultipartAsync(provider); var formData = new NameValueCollection(); foreach (var httpContent in provider.Contents)
{
var formFileName = httpContent.Headers.ContentDisposition?.FileName?.Trim('\"');
var formContentType = httpContent.Headers?.ContentType?.ToString(); if (!string.IsNullOrEmpty(formFileName) && !string.IsNullOrEmpty(formContentType))
{
//文件数据
using (var fileStream = new FileStream(root, FileMode.Create))
{
await httpContent.CopyToAsync(fileStream);
}
}
else
{
//表单参数
var formFieldName = httpContent.Headers.ContentDisposition.Name; var formFieldValue = await httpContent.ReadAsStringAsync(); formData.Add(formFieldName, formFieldValue);
}
}
.NET Core Web APi FormData文件上传
HTML和脚本在上述已经提供,这里我们只需关注APi获取即可。在.NET Core中没有专门提供获取FormData数据的APi,那么我们是如何获取的呢?网上找了一大圈大部分是来自广告网站CSDN,不过这些文章都是转载的博客园,都是如下这样获取
[Route("api/[controller]/[action]")]
[ApiController]
public class UploadController : ControllerBase
{
public IActionResult Upload()
{
var files = Request.Form.Files;
return Ok();
}
}

如上也没问题,我能说你这思路还停留在.NET Web APi吗,啥年代了,还通过请求上下文去获取,.NET Core灵活绑定机制使用起来它不香吗,通过如下直接绑定岂不完事

此时有的童鞋又有疑问了,上传不仅仅包括文件还包括参数,比如上述还有标题,那该如何是好,啊,这个问题,.NET Core的强类型绑定机制它不香吗,如下定义强类型:
public class ExampleUpload
{
public string Title { get; set; }
public List<IFormFile> Files { get; set; }
}
注意:绑定参数时一定要使用[FromForm],否则将出现请求415,同时也要将前端Ajax FormData文件的参数名和强类型参数名一致。
[Route("api/[controller]/[action]")]
[ApiController]
public class UploadController : ControllerBase
{
public IActionResult Upload([FromForm]ExampleUpload example)
{
return Ok();
}
}

总结
.NET Core用起来就是这么流畅和舒适,它也是真的香啊,好了,关于此二者多文件上传暂且总结于此,我们下节再会。
.NET和.NET Core Web APi FormData多文件上传对比的更多相关文章
- ASP.NET Core WEB API 使用element-ui文件上传组件el-upload执行手动文件文件,并在文件上传后清空文件
前言: 从开始学习Vue到使用element-ui-admin已经有将近快两年的时间了,在之前的开发中使用element-ui上传组件el-upload都是直接使用文件选取后立即选择上传,今天刚好做了 ...
- ASP.NET 异步Web API + jQuery Ajax 文件上传代码小析
该示例中实际上应用了 jquery ajax(web client) + async web api 双异步. jquery ajax post $.ajax({ type: "POST&q ...
- .net core 基于multipart/form-data的文件上传,这里以图片上传为例
首先传递的数据格式大概如下: 然后就可以在后端获取数据了:直接上代码了哈: [HttpPost] ///分别获取 data数据和调用图片上传方法 public async Task< ...
- Multipart/form-data POST文件上传详解
Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...
- Multipart/form-data POST文件上传详解(转)
Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...
- 构建multipart/form-data实现文件上传
构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...
- 百度Web Uploader组件实现文件上传(一)
Web Uploader WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势 ...
- SpringBoot | 第十七章:web应用开发之文件上传
前言 上一章节,我们讲解了利用模版引擎实现前端页面渲染,从而实现动态网页的功能,同时也提出了兼容jsp项目的解决方案.既然开始讲解web开发了,我们就接着继续往web这个方向继续吧.通常,我们在做we ...
- SpringBoot --web 应用开发之文件上传
原文出处: oKong 前言 上一章节,我们讲解了利用模版引擎实现前端页面渲染,从而实现动态网页的功能,同时也提出了兼容jsp项目的解决方案.既然开始讲解web开发了,我们就接着继续往web这个方向继 ...
随机推荐
- 数据可视化实例(十六):有序条形图(matplotlib,pandas)
排序 (Ranking) 棒棒糖图 (Lollipop Chart) 棒棒糖图表以一种视觉上令人愉悦的方式提供与有序条形图类似的目的. https://datawhalechina.github.io ...
- Spring Boot中Tomcat是怎么启动的
Spring Boot一个非常突出的优点就是不需要我们额外再部署Servlet容器,它内置了多种容器的支持.我们可以通过配置来指定我们需要的容器. 本文以我们平时最常使用的容器Tomcat为列来介绍以 ...
- 导出数据到Excel的时候报JAVA.LANG.NOSUCHMETHODERROR: ORG.APACHE.POI.SS.USERMODEL.CELLSTYLE.SETVERTICALALIGNMENT(LORG/APACHE/POI/SS/USERMODEL/VERTICALALIGNMENT;)V
JAVA.LANG.NOSUCHMETHODERROR: ORG.APACHE.POI.SS.USERMODEL.CELLSTYLE.SETVERTICALALIGNMENT(LORG/APACHE/ ...
- SpringCloud或SpringBoot+Mybatis-Plus利用AOP+mybatis插件实现数据操作记录及更新对比
引文 本文主要介绍如何使用Spring AOP + mybatis插件实现拦截数据库操作并根据不同需求进行数据对比分析,主要适用于系统中需要对数据操作进行记录.在更新数据时准确记录更新字段 核心:AO ...
- CentOS开机启动不了修复
1,如果启动时进度条,先修改为日志启动 启动后快速按任何键(Enter除外)进入如下界面 在按e进入 选择第二个选项卡 在按e进入将红色部分 rhgb quiet 删除,然后按Enter,在按b重启 ...
- Ethical Hacking - GAINING ACCESS(23)
CLIENT SIDE ATTACK - BeEF Framework Hooking targets using MITMF Tools: MITMF and BeEF Start BeEF and ...
- Android 性能优化 ---- 内存优化
1.Android内存管理机制 1.1 Java内存分配模型 先上一张JVM将内存划分区域的图 程序计数器:存储当前线程执行目标方法执行到第几行. 栈内存:Java栈中存放的是一个个栈帧,每个栈帧对应 ...
- vuex : 用vuex控制侧栏点亮状态
上代码. xxx.vue <template> <div id="xxx"> <div class="layout"> &l ...
- java-把生成的随机数,指定范围(如:100-200),指定打印次数(如:50次),并进行去重。
package main.demo; public class Demo4 { /** * 随机指定范围内N个不重复的数 * 最简单最基本的方法 * @param min 指定范围最小值 * @par ...
- Java 异常处理专题,从入门到精通
内置异常和Throwable核心方法 Java内置异常 可查异常(必须要在方法里面捕获或者抛出) ClassNoFoundException 应⽤程序试图加载类,找不到对应的类 IllegalAcce ...