缓冲和流式传输是上传文件的两种常用方案,这里主要演示流式传输。
1.Net Core MVC Form提交方式:
前端页面 form表单提交:
<form id="uploadForm">
图片上传: <input type="file" name="file" multiple value="选择" onchange="doUpload()" id="ajaxfile" />
</form>
<script type="text/javascript">
//图片上传
function doUpload()
{
var formData = new FormData($("#uploadForm")[0]);
$.ajax({
url: '@Url.Action("FileSave", "FileUpload")',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
//成功后执行的方法
},
error: function (returndata) {
//上传失败执行的方法
}
});
}
</script>
后端方法:
采用的流式处理,请求收到文件,然后应用直接处理或者保存。这种传输无法提高性能,但优点是可降低上传时对内存或磁盘空间的需求。
通过流(stream)把请求收到的文件拷贝到系统指定的文件中。
[HttpPost]
public async Task<IActionResult> FileSave()
{
//获取Form提交的文件
var files = Request.Form.Files;
long size = files.Sum(f => f.Length);
string webRootPath = _hostingEnvironment.WebRootPath; //物理路径
string contentRootPath = _hostingEnvironment.ContentRootPath;
string showfilePath = "";
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
int count = formFile.FileName.Split('.').Length;
string fileExt = formFile.FileName.Split('.')[count - 1]; //文件扩展名,不含“.”
long fileSize = formFile.Length; //获得文件大小,以字节为单位
string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
#region 文件夹不存在则创建
var filePath = webRootPath + "/upload";
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
#endregion
#region 文件不存在则新建
filePath = webRootPath + "/upload/" + newFileName;
showfilePath = "upload/" + newFileName;
FileHelper.CreateFile(filePath);
#endregion
//把上传的图片复制到指定的文件中
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
return Ok(new { count = files.Count, savepath = showfilePath });
}
2.基于Base64的方式
前端用Vue提交,调用后端接口
vue提交用FormData方式,params方提交的参数会放到Url末尾,导致过长超出,这里用FormData的方式提交
提交时传递的参数要通过FormData对象来添加
Vue提交方法:
//上传图片
afterRead(file) {
// 此时可以自行将文件上传至服务器
let obj={};
var imgurl=file.content
//需要将文件的地址 需要去掉base64头部标签 这里简单用replace替换
imgurl = imgurl.replace("data:image/jpeg;base64,", "");
//获取图片的格式
var Img=file.file.name.split('.')[1]
//创建formdata对象 传递参数
var formdata=new FormData();
formdata.append("fileBase64",imgurl);//添加一条数据
formdata.append("fileExt",Img);//添加一条数据
//ajax调用接口,ajax的参数配置
this.$ajax({
method: 'post',
dataType:'json',
url: "http://*****/FileUpload/UploadBase64",
contentType : false,// 告诉jQuery不要去设置Content-Type请求头
processData: false,// 告诉jQuery不要去处理发送的数据,
beforeSend : function(req) {
req.setRequestHeader('Content-Type', 'application/json'); ///加这一行解决问题
},
data: formdata
}).then(res=>{
//图片上传成功后 执行的操作
var msg=res.data.msg
}).catch(error =>{
console.log(error)
})
},
后端方法:原理和1基本相同
[HttpPost]
public string UploadBase64(string fileBase64,string fileExt)
{
TableData data = new TableData();
byte[] bytes = ToBytes_FromBase64Str(fileBase64);
//var fileExtension = Path.GetExtension(fileName);
string webRootPath = _hostingEnvironment.WebRootPath;
string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
var filePath = webRootPath + "/upload";
var RetfilePath = "upload/" + newFileName;
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
filePath = webRootPath + "/upload/" + newFileName;
try
{
data.code = 200;
FileStream fs = new FileStream(filePath, FileMode.CreateNew);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
data.msg = RetfilePath;
}
catch (Exception ex)
{
data.code = 500;
data.msg = "newFileName:"+ newFileName+"Error:"+ex.Message;
}
return JsonHelper.Instance.Serialize(data);
}
附:FileHelper类 和TableData类
public static class FileHelper
{
/// <summary>
/// 拷贝文件
/// </summary>
/// <param name="orignFile">原始文件</param>
/// <param name="newFile">新文件路径</param>
public static void FileCoppy(string orignFile, string newFile)
{
if (string.IsNullOrEmpty(orignFile))
{
throw new ArgumentException(orignFile);
}
if (string.IsNullOrEmpty(newFile))
{
throw new ArgumentException(newFile);
}
System.IO.File.Copy(orignFile, newFile, true);
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="path">路径</param>
public static void FileDel(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException(path);
}
System.IO.File.Delete(path);
}
/// <summary>
/// 移动文件
/// </summary>
/// <param name="orignFile">原始路径</param>
/// <param name="newFile">新路径</param>
public static void FileMove(string orignFile, string newFile)
{
if (string.IsNullOrEmpty(orignFile))
{
throw new ArgumentException(orignFile);
}
if (string.IsNullOrEmpty(newFile))
{
throw new ArgumentException(newFile);
}
System.IO.File.Move(orignFile, newFile);
}
//创建路径
public static void CreatePath(string FilePath)
{
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
}
//创建文件
public static void CreateFile(string FilePath)
{
if (!File.Exists(FilePath))
{
FileStream fs = File.Create(FilePath);
fs.Close();
}
}
}
public class TableData
{
/// <summary>
/// 状态码
/// </summary>
public int code;
/// <summary>
/// 操作消息
/// </summary>
public string msg;
/// <summary>
/// 总记录条数
/// </summary>
public int count;
/// <summary>
/// 数据内容
/// </summary>
public dynamic data;
public TableData()
{
code = 200;
msg = "加载成功";
}
}
演示效果
第二种
.netcore 取消了之前.netframework的HttpPostedFileBase 。
整理了一个上传文件的流程,可以选择跳转或不跳转页面。
#引入jQuery以及 jQuery的jQuery.form.js,一定要先引入jQuery
<script src="../../../content/js/jquery.3.0.1.js"></script>
<script src="../../../content/js/jquery.form.js"></script>
<script>
function RuturnLoginResult() {
$('#UserLoginFrom').ajaxSubmit(function (data) {
alert(data);
})
return false;//这里必须要返回false,不然依然会跳转。
}
</script>
<body>
<form class="form-horizontal" method="post" enctype="multipart/form-data" action="/SysManager/FileSave" οnsubmit="return RuturnLoginResult();" id="UserLoginFrom">
<div>
<div>
<div class="col-md-6 input-group">
<span class="input-group-addon">选择恢复文件</span>
<input class="col-md-6" type="file" name="files" multiple /> <span class="input-group-btn">
<button type="button" class="btn btn-info btn-search" οnclick="dump()">...</button>
</span>
</div>
<input class="col-md-3 btn btn-info btn-search" type="submit" value="恢复备份" />
</div>
</div>
</form>
</body>
后台
public async Task<IActionResult> FileSave(List<IFormFile> files)
{
// fil = files;
var file = Request.Form.Files;
long size = files.Sum(f => f.Length);
string webRootPath = hostingEnvironment.WebRootPath;
string contentRootPath = hostingEnvironment.ContentRootPath;
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
string fileExt = "doc";
/// string fileExt = GetFileExt(formFile.FileName); //文件扩展名,不含“.”
long fileSize = formFile.Length; //获得文件大小,以字节为单位
string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
var filePath = webRootPath + "/upload/" + formFile.FileName;
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
return Json(filePath );
}