首先本文參考的是,感謝博主:
net6WebApi上傳下載文件_cduoa的博客-CSDN博客_webapi下載文件
在博主的基礎(chǔ)上,增加了新的功能,代碼中有注明,并且使用VUE3前端實現(xiàn)。
后端部分:
1.首先建立IFileService文件
namespace net6ApiUploadAndDownload
{
public interface IFileService
{
void UploadFile(List<IFormFile> files, string subDirectory);
(string fileType, byte[] archiveData, string archiveName) DownloadFiles(string subDirectory); //返回3個值
string SizeConverter(long bytes);
}
}
2.建立FileService文件
using System.IO.Compression;
namespace net6ApiUploadAndDownload;
public class FileService : IFileService
{
#region Property
private readonly IWebHostEnvironment webHostEnvironment;
#endregion
#region Constructor
public FileService(IWebHostEnvironment webHostEnvironment)
{
this.webHostEnvironment = webHostEnvironment;
}
#endregion
#region Upload File
public void UploadFile(List<IFormFile> files, string subDirectory)
{
subDirectory = subDirectory ?? string.Empty;
var target = Path.Combine(webHostEnvironment.ContentRootPath, subDirectory);
Directory.CreateDirectory(target);
//files.ForEach(async file =>
//{
// if (file.Length <= 0) return;
// var filePath = Path.Combine(target, file.FileName);
// await using var stream = new FileStream(filePath, FileMode.Create);
// await file.CopyToAsync(stream);
//});
//此處使用async,超過30M的話,會報錯
files.ForEach(file =>
{
if (file.Length <= 0) return;
var filePath = Path.Combine(target, file.FileName);
using var stream = new FileStream(filePath, FileMode.Create);
file.CopyTo(stream);
});
}
#endregion
#region Download File
public (string fileType, byte[] archiveData, string archiveName) DownloadFiles(string subDirectory)
{
var zipName = $"archive-{DateTime.Now:yyyy_MM_dd-HH_mm_ss}.zip";
//這里進行判斷,既能下載文件夾的內(nèi)容,又能下載單個文件
List<string> files = new List<string>();
if (subDirectory.Split('.').Length > 1) //上傳的是單個文件
{
files.Add(Path.Combine(webHostEnvironment.ContentRootPath, subDirectory));
}
else //上傳的是文件夾的內(nèi)容
{
files = Directory.GetFiles(Path.Combine(webHostEnvironment.ContentRootPath, subDirectory)).ToList();
}
using var memoryStream = new MemoryStream();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
files.ForEach(file =>
{
var theFile = archive.CreateEntry(Path.GetFileName(file));
using var binaryWriter = new BinaryWriter(theFile.Open());
binaryWriter.Write(File.ReadAllBytes(file));
});
}
return ("application/zip", memoryStream.ToArray(), zipName);
}
#endregion
#region Size Converter
public string SizeConverter(long bytes)
{
var fileSize = new decimal(bytes);
var kilobyte = new decimal(1024);
var megabyte = new decimal(1024 * 1024);
var gigabyte = new decimal(1024 * 1024 * 1024);
return fileSize switch
{
_ when fileSize < kilobyte => "Less then 1KB",
_ when fileSize < megabyte =>
$"{Math.Round(fileSize / kilobyte, 0, MidpointRounding.AwayFromZero):##,###.##}KB",
_ when fileSize < gigabyte =>
$"{Math.Round(fileSize / megabyte, 2, MidpointRounding.AwayFromZero):##,###.##}MB",
_ when fileSize >= gigabyte =>
$"{Math.Round(fileSize / gigabyte, 2, MidpointRounding.AwayFromZero):##,###.##}GB",
_ => "n/a"
};
}
#endregion
}
3.增加FileController文件
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
namespace net6ApiUploadAndDownload.Controllers
{
[Route("api/[controller]/action")]
[ApiController]
public class FileController : ControllerBase
{
private readonly IFileService fileService;
public FileController(IFileService fileService)
{
this.fileService = fileService;
}
/// <summary>
/// 上傳功能
/// </summary>
/// <param name="formFiles">上傳的文件</param>
/// <param name="subDirectory">把文件上傳到的具體的路徑</param>
/// <returns></returns>
[HttpPost(nameof(Upload))]
//[RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = long.MaxValue)]
[RequestSizeLimit(long.MaxValue)] //默認是上傳30M,加上之后可,可以增大
public IActionResult Upload([Required] List<IFormFile> formFiles, [Required] string subDirectory)
{
try
{
if (formFiles.Count > 0)
{
}
fileService.UploadFile(formFiles, subDirectory);
return Ok(new { formFiles.Count, Size = fileService.SizeConverter(formFiles.Sum(f => f.Length)) });
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
/// <summary>
/// 下載功能
/// </summary>
/// <param name="subDirectory">下載文件夾的路徑或者下載的文件路徑</param>
/// <returns></returns>
[HttpGet(nameof(Download))]
public IActionResult Download([Required] string subDirectory)
{
try
{
var (fileType, archiveData, archiveName) = fileService.DownloadFiles(subDirectory);
return File(archiveData, fileType, archiveName);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
}
4.Program文件中,進行配置和跨域的處理
using net6ApiUploadAndDownload;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<IFileService, FileService>(); //用AddTransient注入,每次都請求不同的實例
//配置跨域服務(wù)
builder.Services.AddCors(options =>
{
options.AddPolicy("cors", p =>
{
p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors("cors"); //跨域
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
5.運行后的效果
6.Swagger就不用測試了,我們使用postman來測試一下上傳的接口
先輸入路徑
再選擇content-type?
最后選擇form-data,點擊發(fā)送按鈕,就會看到返回的路徑了
至此,后端完成。?
前端部分:
1.首先使用HBuilder X建立一個可運行的界面
2.然后寫入HelloWorld.vue代碼
<template>
<el-upload ref="upload" action="#" multiple :file-list="fileList" :on-change="fileOnChange" :auto-upload="false">
<el-button type="primary">上傳圖片</el-button>
</el-upload>
<el-button type="primary" @click="confirm">確定</el-button>
<el-button type="success" @click="download">下載</el-button>
</template>
<script setup>
import {
reactive
} from 'vue'
import axios from 'axios'
const fileList = reactive([])
const formData = new FormData()
const fileOnChange = (file) => {
//下面部分可以對文件進行判斷
const isIMAGE = (file.raw.type === 'image/jpeg' || file.raw.type === 'image/png' || file.raw.type ===
'image/gif');
const isLt1M = file.size / 1024 / 1024 < 1;
// if (!isIMAGE) {
// alert('上傳文件只能是圖片格式!');
// return false;
// }
// if (!isLt1M) {
// alert('上傳文件大小不能超過 1MB!');
// return false;
// }
var reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = function(e) {
//console.log(e.currentTarget.result) //圖片的base64數(shù)據(jù)
//str = str.replace(/^data:image\/\w+;base64,/, "")
}
if (file.status === 'ready') {
console.log(1)
fileList.push(file)
}
}
//內(nèi)置地址
let path = `C:\\Users\\Administrator\\Desktop\\圖片\\聲音`
const download = () => {
console.log(2)
window.location.href = `https://localhost:7065/api/File/action/Download?subDirectory=${path}`
// axios.get(`https://localhost:7065/api/File/action/Download?subDirectory=${path}`).then((res) => {
// console.log(res)
// if (res.status === 200) {
// console.log(res.data.size)
// }
// })
}
const confirm = () => {
console.log(formData.has('formFiles'))
fileList.forEach((item, index) => {
formData.append("formFiles", item.raw)
//formData.append("subDirectory", 'file')
console.log(item + index)
console.log(2)
})
console.log(formData.has('formFiles'))
uploadFiles(formData)
}
function uploadFiles(data) {
axios.post("https://localhost:7065/api/File/action/Upload?subDirectory=1", data).then((res) => {
console.log(res)
if (res.status === 200) {
console.log(res.data.size)
}
})
}
</script>
3.點擊上傳功能
點擊上傳3張圖片,再點擊確定按鈕,可以看到下面有返回圖片的大小
此時api中也就有了圖片,1是文件夾的路徑
4.點擊下載功能
直接點擊下載按鈕,就會看到內(nèi)置路徑的文件,就會自動下載
5.源碼
net6ApiUploadAndDownload: net6ApiUploadAndDownload,VUE3上傳和下載功能文章來源:http://www.zghlxwxcb.cn/news/detail-408671.html
來源:.net6Api后臺+VUE3前端實現(xiàn)上傳和下載文件全過程-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-408671.html
到了這里,關(guān)于.net6Api后臺+VUE3前端實現(xiàn)上傳和下載文件全過程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!