後端服務使用的是Asp.net WebApi,至於如果有環境搭建或者怎麼引入上傳控制項這一類的問題,請自行百度,都有手冊多看幾遍。 在此記錄的是核心的一些代碼,沒有給出界面UI,因為重點是給出思路和怎麼用 1.頁面引入nz-upload 1.我們在Angular頁面引入控制項,主要介紹2個重要的屬性,其 ...
後端服務使用的是Asp.net WebApi,至於如果有環境搭建或者怎麼引入上傳控制項這一類的問題,請自行百度,都有手冊多看幾遍。
在此記錄的是核心的一些代碼,沒有給出界面UI,因為重點是給出思路和怎麼用
1.頁面引入nz-upload
1.我們在Angular頁面引入控制項,主要介紹2個重要的屬性,其他的建議讀下手冊
- 1.1. nzFileList的值就是雙向綁定的文件列表,就是最終需要傳到後端的,你如果需要展示那也可以取這裡的值
- 1.2. nzBeforeUpload 一定要使用
箭頭函數
,箭頭函數
,箭頭函數
,不要問為什麼重覆,踩過坑的,上傳之前執行的事件
<nz-upload [nzAction]="''" [(nzFileList)]="fileList" nzMultiple [nzLimit]="0" [nzShowUploadList]="false"
[nzBeforeUpload]="beforeUpload">
<button [disabled]="false" nz-button nzType="primary" nz-popover nzPopoverContent="Upload File">
<i nz-icon nzType="upload"></i>
</button>
</nz-upload>
2.鉤子事件和上傳事件
1.鉤子事件
就是上傳事件之前執行的事件,可以做一些校驗等操作,當然你也可以寫在上傳事件中,隨處可見的AOP
fileList: NzUploadFile[] = [];
beforeUpload = (file: NzUploadFile): boolean => {
//判斷文件大小
const isLt4M = file.size! / 1024 / 1024 < 4;
if (!isLt4M) {
this.message.error('Message.File.SizeFile');
return false;
}
this.fileList = this.fileList.concat(file);
return true;
}
2.上傳事件
用於將文件信息提交到後端
async handleUpload() {
const formData = new FormData();
//將文件綁定到FormData中
this.fileList.forEach((file: any) => {
formData.append("files[]", file);
});
//給後端文件服務標識來源於什麼系統
formData.append("system", "OA");
//給後端文件服務標識是什麼類型的附件
formData.append('annexType', "附件類型");
//使用Post調用文件服務
this.httpclient.post<any>("192.168.0.105/api/FileServer/UploadFile", formData).toPromise();
}
3.下載文件
1.定義下載對象,然後調用後端下載api介面
downLoadFile(file: Attachment): void {
const DownloadRequest = {
FileFullPath: 文件伺服器摘要返回的文件路徑,
FileId: 文件伺服器摘要返回的文件ID,
FullFileName: 文件伺服器摘要返回的文件名稱,
};
let head = new HttpHeaders({ 'Content-Type': 'application/json' });
//調用文件下載服務
this.httpclient.post<any>("192.168.0.105/api/FileServer/DownloadFile",DownloadRequest,{ headers: head, responseType: 'arraybuffer' }).subscribe(
(result) => {
if ('msSaveOrOpenBlob' in navigator) {
const nav = window.navigator as any;
nav.msSaveOrOpenBlob(
new Blob([]),
DownloadRequest.FullFileName
);
return;
} else {
const url = window.URL.createObjectURL(new Blob([result]));
const link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.setAttribute('download', DownloadRequest.FullFileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
return url;
}
})
3.後端WebAPI服務
-
在這裡實現思路為文件伺服器保存文件,並生成文件一對一的
摘要信息
,返回到客戶端,客戶端收到上傳成功的摘要信息,然後將摘要Id
與業務數據綁定,存到業務資料庫,下次載入數據,根據摘要Id
來找到對應的文件信息,然後訪問文件伺服器下載文件。 -
這裡暫時不考慮,如果多個文件是否完整上傳,中間有失敗的情況,為了伺服器安全,後端和前端應適當過濾篩選出一些不能被上傳的文件尾碼,例如DLL exe這些,這隻是個小建議,當然您可以使用,你所喜歡的任何文件服務中間件,作為你的文件伺服器
3.控制器中接收文件上傳內容,存入本地磁碟文件夾,然後返迴文件信息的摘要
包含如下
- 文件對應生成的唯一id
- 文件存儲文件夾路徑
- 文件內容長度
- 文件尾碼名
- 文件是否被壓縮
控制器接收
[HttpPost]
[Route("api/FileServer/UploadFile")]
public HttpResponseMessage UploadFile()
{
HttpRequest httpRequest = HttpContext.Current.Request;
string config = httpRequest.Params["system"].Trim();
string annexType = httpRequest.Params["annexType"].Trim();
if (string.IsNullOrEmpty(config) || string.IsNullOrEmpty(annexType))
{
return Request.CreateResponse(HttpStatusCode.BadRequest, "config and annexType is required.");
}
string FilePath = ConfigurationManager.AppSettings[config];
var filePath = HttpContext.Current.Server.MapPath(FilePath + annexType) + "\\";
if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
return UploadFileHandler(httpRequest,filePath);
}
文件處理方法
[NonAction]
public HttpResponseMessage UploadFileHandler(HttpRequest httpRequest, string filePath)
{
try
{
HttpResponseMessage result = null;
if (httpRequest.Files.Count > 0)
{
//文件信息的摘要
List<FileData> ResponseData = new List<FileData>();
for (int i = 0; i < httpRequest.Files.Count; i++)
{
FileData fileData = new FileData();
var postedFile = httpRequest.Files[i];
string guid = Guid.NewGuid().ToString().ToUpper();
//一個一個文件保存到本地磁碟
postedFile.SaveAs(filePath + guid);
fileData.FileId = guid;
fileData.FullFileName = postedFile.FileName;
fileData.FileFullPath = filePath + guid;
fileData.ContentLength = postedFile.ContentLength;
fileData.Extension = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
fileData.isZipFile = false;
ResponseData.Add(fileData);
}
result = Request.CreateResponse(HttpStatusCode.Created, ResponseData);
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
catch (Exception e)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.ReasonPhrase = e.Message;
return response;
}
}
2.下載文件服務
[HttpPost]
[Route("api/FileServer/DownloadFile")]
public HttpResponseMessage DownloadFile(DownloadRequest request)
{
try
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(request.FileFullPath);
if (!fileInfo.Exists)
{
response = new HttpResponseMessage(HttpStatusCode.NotFound);
response.ReasonPhrase = "File does not exists.";
return response;
}
FileStream stream = new FileStream(request.FileFullPath, FileMode.Open);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/force-download");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = HttpUtility.UrlEncode(request.FullFileName)
};
response.Headers.Add("Access-Control-Expose-Headers", "FileName");
response.Headers.Add("FileName", HttpUtility.UrlEncode(request.FullFileName));
return response;
}
catch (Exception e)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.ReasonPhrase = e.Message;
return response;
}
}