緩衝和流式傳輸是上傳文件的兩種常用方案,這裏主要演示流式傳輸。
1.Net Core MVC Form提交方式:
前端頁面 form表單提交:
<form id="uploadForm">
圖片上傳: <input type="file" name="file" multiple value="選擇" οnchange="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 );
}