diff --git a/src/BootstrapBlazor.Shared/Samples/Uploads.razor.cs b/src/BootstrapBlazor.Shared/Samples/Uploads.razor.cs index 099e2c5627b..ed7b77af1ba 100644 --- a/src/BootstrapBlazor.Shared/Samples/Uploads.razor.cs +++ b/src/BootstrapBlazor.Shared/Samples/Uploads.razor.cs @@ -150,7 +150,7 @@ private async Task SaveToFile(UploadFile file) var fileName = Path.Combine(uploaderFolder, file.FileName); ReadToken ??= new CancellationTokenSource(); - ret = await file.SaveToFile(fileName, MaxFileLength, ReadToken.Token); + ret = await file.SaveToFileAsync(fileName, MaxFileLength, ReadToken.Token); if (ret) { diff --git a/src/BootstrapBlazor/Extensions/UploadFileExtensions.cs b/src/BootstrapBlazor/Extensions/UploadFileExtensions.cs new file mode 100644 index 00000000000..118154a014f --- /dev/null +++ b/src/BootstrapBlazor/Extensions/UploadFileExtensions.cs @@ -0,0 +1,209 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using Microsoft.AspNetCore.Components.Forms; + +namespace BootstrapBlazor.Components; + +/// +/// UploadFile 扩展方法类 +/// +public static class UploadFileExtensions +{ + /// + /// 获取 base64 格式图片字符串 + /// + /// + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + public static async Task RequestBase64ImageFileAsync(this UploadFile upload, string format, int maxWidth, int maxHeight, long maxAllowedSize = 512000, CancellationToken token = default) + { + if (upload.File != null) + { + try + { + var imageFile = await upload.File.RequestImageFileAsync(format, maxWidth, maxHeight); + using var fileStream = imageFile.OpenReadStream(maxAllowedSize, token); + using var memoryStream = new MemoryStream(); + await fileStream.CopyToAsync(memoryStream, token); + upload.PrevUrl = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}"; + upload.Uploaded = true; + } + catch (Exception ex) + { + upload.Code = 1004; + upload.PrevUrl = null; + upload.Error = ex.Message; + } + } + } + + /// + /// 保存到文件方法 已过期 + /// + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use SaveToFileAsync method")] + public static Task SaveToFile(this UploadFile upload, string fileName, long maxAllowedSize = 512000, CancellationToken token = default) => upload.SaveToFileAsync(fileName, maxAllowedSize, token); + + /// + /// 保存到文件方法 + /// + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + public static async Task SaveToFileAsync(this UploadFile upload, string fileName, long maxAllowedSize = 512000, CancellationToken token = default) + { + var ret = false; + if (upload.File != null) + { + // 文件保护,如果文件存在则先删除 + if (File.Exists(fileName)) + { + try + { + File.Delete(fileName); + } + catch (Exception ex) + { + upload.Code = 1002; + upload.Error = ex.Message; + } + } + + if (upload.Code == 0) + { + var folder = Path.GetDirectoryName(fileName); + if (!string.IsNullOrEmpty(folder) && !Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + } + + using var uploadFile = File.OpenWrite(fileName); + try + { + // 打开文件流 + var stream = upload.File.OpenReadStream(maxAllowedSize, token); + var buffer = new byte[4 * 1096]; + int bytesRead = 0; + double totalRead = 0; + + // 开始读取文件 + while ((bytesRead = await stream.ReadAsync(buffer, token)) > 0) + { + totalRead += bytesRead; + await uploadFile.WriteAsync(buffer.AsMemory(0, bytesRead), token); + + if (upload.UpdateCallback != null) + { + var percent = (int)((totalRead / upload.File.Size) * 100); + if (percent > upload.ProgressPercent) + { + upload.ProgressPercent = percent; + upload.UpdateCallback(upload); + } + } + } + upload.Uploaded = true; + ret = true; + } + catch (Exception ex) + { + upload.Code = 1003; + upload.Error = ex.Message; + } + } + } + return ret; + } + + /// + /// 获得图片字节数组方法 + /// + /// + /// + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + [Obsolete("Use GetBytesAsync method")] + public static Task GetByteArray(this UploadFile upload, string format, int maxWidth, int maxHeight, long maxAllowedSize = 512000, CancellationToken token = default) => upload.GetBytesAsync(format, maxWidth, maxHeight, maxAllowedSize, token); + + /// + /// 获得图片字节数组方法 + /// + /// + /// + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + public static async Task GetBytesAsync(this UploadFile upload, string format, int maxWidth, int maxHeight, long maxAllowedSize = 512000, CancellationToken token = default) + { + byte[]? ret = null; + if (upload.File != null) + { + try + { + var imageFile = await upload.File.RequestImageFileAsync(format, maxWidth, maxHeight); + using var fileStream = imageFile.OpenReadStream(maxAllowedSize, token); + using var memoryStream = new MemoryStream(); + await fileStream.CopyToAsync(memoryStream, token); + ret = memoryStream.ToArray(); + } + catch (Exception ex) + { + upload.Code = 1004; + upload.Error = ex.Message; + upload.PrevUrl = null; + } + } + return ret; + } + + /// + /// 获得图片字节数组方法 + /// + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + public static async Task GetBytesAsync(this UploadFile upload, long maxAllowedSize = 512000, CancellationToken token = default) + { + byte[]? ret = null; + if (upload.File != null) + { + try + { + using var fileStream = upload.File.OpenReadStream(maxAllowedSize, token); + using var memoryStream = new MemoryStream(); + await fileStream.CopyToAsync(memoryStream, token); + ret = memoryStream.ToArray(); + } + catch (Exception ex) + { + upload.Code = 1004; + upload.Error = ex.Message; + upload.PrevUrl = null; + } + } + return ret; + } +} diff --git a/test/UnitTest/Components/UploadTest.cs b/test/UnitTest/Components/UploadTest.cs index bb1c7398905..336bb9175c6 100644 --- a/test/UnitTest/Components/UploadTest.cs +++ b/test/UnitTest/Components/UploadTest.cs @@ -527,7 +527,7 @@ public void ButtonUpload_ShowProgress_Ok() pb.Add(a => a.ShowProgress, true); pb.Add(a => a.OnChange, async file => { - await file.SaveToFile("1.txt"); + await file.SaveToFileAsync("1.txt"); }); }); var input = cut.FindComponent(); @@ -680,7 +680,7 @@ public async Task CardUpload_Ok() pb.Add(a => a.ShowProgress, true); pb.Add(a => a.OnChange, async file => { - await file.SaveToFile("1.txt"); + await file.SaveToFileAsync("1.txt"); }); }); var input = cut.FindComponent();