Blazor不得不說真是好東西,極大的提升了開發效率,很多的頁面互動功能基本上隻需要寫很少的代碼就能實作了,而且還是無js實作,你也絕對沒有想到過,Blazor實作檔案上傳是有多麼簡單!
先說結論:Blazor實作帶進度顯示的檔案上傳真的很簡單!效果看圖:
實作這麼一個小功能,僅僅隻花了不到50行的代碼就實作了,接下來就給大家分享下案例實作吧。
首先引入Tewr.Blazor.FileReader包,這個包能夠提供檔案上傳的流式讀取,這樣便可以實作在服務端對上傳檔案進行一邊上傳一遍寫檔案的操作。
配置依賴注入
services.AddFileReaderService();
接下來我們先進行頁面布局,很簡單,再聲明兩個變量用于顯示進度和顯示圖檔
<input type="file"/><button>上傳檔案</button>
<div>
@if (!string.IsNullOrEmpty(_src))
{
<img src="@_src" width="600px" />
}
else
{
<p>@progress</p>
}
</div>
然後在元件中注入IFileReaderService服務
@using Tewr.Blazor.FileReader
@inject IFileReaderService fileReaderService;
為了讓檔案框能夠和C#代碼進行互動,是以需要将它通過ElementReference引用起來
<input @ref=inputTypeFileElement type="file" /><button>上傳檔案</button>
<div>
@if (!string.IsNullOrEmpty(_src))
{
<img src="@_src" width="600px" />
}
else
{
<p>@progress</p>
}
</div>
@code {
private ElementReference inputTypeFileElement;
private string _src;
private string progress;
}
給按鈕綁定事件,按鈕觸發後通過fileReaderService進行檔案流的讀取,接下來便是正常的二進制資料copy操作,可以拿到檔案的傳輸進度,計算之後便能顯示到頁面中
<button @onclick=ReadFile>上傳檔案</button>
public async Task ReadFile()
{
_src = "";
foreach (var file in await fileReaderService.CreateReference(inputTypeFileElement).EnumerateFilesAsync())
{
await using var fileStream = await file.OpenReadAsync();
var buffer = new byte[2048];
var finalBuffer = new byte[fileStream.Length];
int count;
int totalCount = 0;
while ((count = await fileStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
Buffer.BlockCopy(buffer, 0, finalBuffer, totalCount, count);
totalCount += count;
progress = "檔案上傳中 " + (int)(totalCount * 100.0 / fileStream.Length) + "%";
StateHasChanged();
}
_src = $"data:image/jpg;base64,{Convert.ToBase64String(finalBuffer)}";
progress = "";
StateHasChanged();
}
}
完整代碼如下:
@page "/counter"
@using Tewr.Blazor.FileReader
@inject IFileReaderService fileReaderService;
<input @ref=inputTypeFileElement type="file" />
<button @onclick=ReadFile>上傳檔案</button>
<div>
@if (!string.IsNullOrEmpty(_src))
{
<img src="@_src" width="600px" />
}
else
{
<p>@progress</p>
}
</div>
@code {
private ElementReference inputTypeFileElement;
private string _src;
private string progress;
public async Task ReadFile()
{
_src = "";
foreach (var file in await fileReaderService.CreateReference(inputTypeFileElement).EnumerateFilesAsync())
{
await using var fileStream = await file.OpenReadAsync();
var buffer = new byte[2048];
var finalBuffer = new byte[fileStream.Length];
int count;
int totalCount = 0;
while ((count = await fileStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
Buffer.BlockCopy(buffer, 0, finalBuffer, totalCount, count);
totalCount += count;
progress = "檔案上傳中 " + (int)(totalCount * 100.0 / fileStream.Length) + "%";
StateHasChanged();
}
_src = $"data:image/jpg;base64,{Convert.ToBase64String(finalBuffer)}";
progress = "";
StateHasChanged();
}
}
}
參考
https://github.com/Tewr/BlazorFileReadergithub.com https://docs.microsoft.com/zh-cn/aspnet/core/blazor/file-uploads?view=aspnetcore-5.0docs.microsoft.com
原作者:懶得勤快
原文連結:Blazor實作檔案上傳帶進度顯示案例分享_懶得勤快的部落格_網際網路分享精神