.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这个方向继 ...
随机推荐
- 03-Django模型知识1
模型:是python中的类对应数据库中的表. ORM:对象关系映射 1.基础示例 学生类模型字段 class blog(models.Model): title = models.CharField( ...
- 年薪30W+高薪测试技术要掌握哪些?
职业技能一 1. 软件测试: 1) 熟练灵活地运用等价类.边界值.判定表法.因果图法等各种方法设计测试用例,包括单元测试.集成测试.系统测试用例设计. 2) 牢固掌握了软件测试计划.测试日报.测试报告 ...
- GPO - File Server Management
Creating disk space usage quotas: File Screening Generate Storage Report, including file edit audit. ...
- 手写SpringBoot自动配置及自定义注解搭配Aop,实现升级版@Value()功能
背景 项目中为了统一管理项目的配置,比如接口地址,操作类别等信息,需要一个统一的配置管理中心,类似nacos. 我根据项目的需求写了一套分布式配置中心,测试无误后,改为单体应用并耦合到项目中.项目中使 ...
- 设计模式:composite模式
目的:使容器和内容具备一致性 实现:将对象组合成树形结构以表示“部分-整体”的层次结构 实例:文件夹中可以包含文件夹也可以包含文件 例子: class Item //接口定义 { public: vi ...
- Shell基本语法---处理海量数据的cut命令
cut命令 cut应用场景:通常对数据进行列的提取 语法:cut [选项] [file] -d #指定分割符 -f #指定截取区域 -c #以字符为单位进行分割 # 以':'为分隔符,截取出/etc/ ...
- java实现单链表的增删改以及排序
使用java代码模拟单链表的增删改以及排序功能 代码如下: package com.seizedays.linked_list; public class SingleLinkedListDemo { ...
- vue中v-for
在vue中我们只要操作数据,就可以渲染和更新数据,这背后的boss就是diff算法 vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设: 1. 俩个相同组件产生类似DOM ...
- BUUCTF-web Easyweb
从这道题学到了挺多 一打开题目就是登陆页面,遂扫描文件检测是否存在文件泄露 用dirsearch扫出了robots.txt,.DS_Store和其他php.DS_Store没有可用信息(buuoj的题 ...
- servlet执行
WEB编程阶段 在WEB编程中,我们可以通过浏览器访问WEB服务器上的资源.WEB服务器就是另一台计算机 浏览器的入口不同(访问路径),访问的资源也不同. 为了灵活实现的不同路径(/hello)执行不 ...