.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这个方向继 ...
随机推荐
- java 基本语法(五) 流程控制(二) 循环结构
1.循环结构的四要素① 初始化条件② 循环条件 --->是boolean类型③ 循环体④ 迭代条件说明:通常情况下,循环结束都是因为②中循环条件返回false了. 2.三种循环结构:2.1 fo ...
- 数据可视化之 图表篇(二)如何用Power BI制作疫情地图?
丁香园制作的这个地图可视化,相信大家每天都会看好几遍,这里不讨论具体数据,仅来探讨一下PowerBI地图技术. 这个地图很简洁,主要有三个特征: 1,使用着色地图,根据数据自动配色 2,只显示中国地图 ...
- Ethical Hacking - Web Penetration Testing(9)
SQL INJECTION Discovering SQLi in GET Inject by browser URL. Selecting Data From Database Change the ...
- 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别
这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...
- 题解 洛谷 P2046 【[NOI2010]海拔】
首先进行贪心,发现海拔有梯度时一定是不优的,最优的情况是海拔像断崖一样上升,也就是左上角有一片海拔高度为\(0\),右下角有一片海拔高度为\(1\). 发现这样的性质后,不难想到用最小割来解决问题,但 ...
- python dict乱码如何解决
定义字典并直接输出,结果输出结果中文是乱码展示 d={'name':'lily','age':18,'sex':'女','no':1121} print d 输出结果: {'age': 18, 'no ...
- LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...
- Residual Attention Network for Image Classification(CVPR 2017)详解
一.Residual Attention Network 简介 这是CVPR2017的一篇paper,是商汤.清华.香港中文和北邮合作的文章.它在图像分类问题上,首次成功将极深卷积神经网络与人类视觉注 ...
- Js数组对象的属性值升序排序,并指定数组中的某个对象移动到数组的最前面
需求整理: 本篇文章主要实现的是将一个数组的中对象的属性值通过升序的方式排序,然后能够让程序可以指定对应的数组对象移动到程序的最前面. 数组如下所示: var arrayData= [{name: & ...
- Kubernetes/K8s CKA认证全套实训视频教程下载
地址: 链接:https://pan.baidu.com/s/1bwEUZTCVzqM3mGjrlISbcg 提取码:r1kx 目录: 目录: │ 1-1.kubernetes理论教程 - 云原生技术 ...