Blazor - Upload File Progressly
Blazor Server App, UploadFile, ProgressBar,上傳檔案可看到進度條
引言
上傳檔案過程可以看到進度條。
Using Blazor Server-side, is it possible to get file progress upload status from from the controller to the client on large files?
參考文章
開發平台
平台: .NET8 語言: C# 框架: Blazor Server App CSS: MudBlazor
關鍵程式碼
可視的上傳檔案元件。前置條件:已拿到 IBorwserFile 了。
@inject IDialogServiceEx dlgSvc
@if (Loading)
{
<MudProgressLinear Color=Color.Info Class="my-2" Value=valuePercent Indeterminate=isUploaded Striped=isUploaded>
<MudText Typo=Typo.body2 Style="background:#0007; color:#EEE; padding:.125em .25em; border-radius:.25em;">
@($"正在上傳: {fileName} ({valuePercent:N1}%)")
</MudText>
</MudProgressLinear>
}
@code {
[Parameter] public bool Loading { get; set; }
//## State
int fileSize = 0;
int fileReadPosition = 0;
string fileName = string.Empty;
//## Property
double valuePercent => (double)fileReadPosition * 100d / (double)fileSize;
bool isUploaded => valuePercent >= 100;
/// 公開指令
public async Task<MemoryStream> StartUploadFileAsync(IBrowserFile file, long maxAllowedSize)
{
try
{
fileName = file.Name;
fileSize = (int)file.Size;
fileReadPosition = 0;
await InvokeAsync(StateHasChanged); // 通知畫面更新進度
// 開始上傳-顯示進度
using var fs = file.OpenReadStream(maxAllowedSize);
MemoryStream ms = new MemoryStream(fileSize);
byte[] buffer = new byte[32 * 1024]; // 32KB buffer
int bytesRead;
while ((bytesRead = await fs.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await ms.WriteAsync(buffer, 0, bytesRead);
fileReadPosition += bytesRead;
await InvokeAsync(StateHasChanged); // 通知畫面更新進度
}
return ms;
}
catch (Exception ex)
{
throw new ApplicationException($"上傳檔案[{file.Name}]失敗!", ex);
}
}
public void Reset()
{
fileName = string.Empty;
fileSize = 0;
fileReadPosition = 0;
}
}
應用
@inject YourOperationBiz bizSvc
@inject IDialogServiceEx dlgSvc
@inject ISnackbar snackSvc
...略...
<MudButton OnClick=HandleUploadFile>
上傳檔案
</MudButton>
@* 可視的上傳檔案元件 *@
<UploadFileProgressly Loading=f_uploading @ref=refUploadFile />
@code {
//@bind-UploadFileList 欲上傳的檔案清單
[Parameter] public List<IBrowserFile> UploadFileList { get; set; }
[Parameter] public EventCallback<List<IBrowserFile>> UploadFileListChanged { get; set; }
// event, 當檔案清單全部上傳完畢,上通知去刷新畫面
[Parameter] public EventCallback OnFilesUploaded { get; set; }
//## Resource
UploadFileProgressly refUploadFile;
const long MAX_ALLOWED_SIZE = 30 * 1024 * 1024; // 30MB, 預設:512KB
//## State
bool f_uploading = false;
async Task HandleUploadFile()
{
try
{
f_uploading = true;
// 依選好的檔案清單,一個一個上傳檔案
while (UploadFileList.Count > 0)
{
// 拿出一個檔案並上傳。
var file = UploadFileList.ElementAt(0);
UploadFileList.RemoveAt(0);
await UploadFileListChanged.InvokeAsync(UploadFileList);
// 開始上傳
if (file.Size > MAX_ALLOWED_SIZE)
{
snackSvc.Add($"檔案[{file.Name}]超過 30MB 不可上傳!", Severity.Error);
continue;
}
//※ 開始上傳-顯示上傳進度
using var ms = await refUploadFile.StartUploadFileAsync(file, MAX_ALLOWED_SIZE);
await bizSvc.UploadFileAsync(ms.ToArray(), file.Name);
snackSvc.Add($"上傳檔案[{file.Name}]成功。", Severity.Success);
await Task.Delay(500);
}
// 已完成,通知去刷新畫面
refUploadFile.Reset();
await OnFilesUploaded.InvokeAsync();
}
catch (Exception ex)
{
dlgSvc.ShowAlert("出現例外!" + ex.Message, "出現例外!");
}
finally
{
f_uploading = false;
}
}
}
沒圖沒真象

(EOF)
Last updated