diff --git a/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.2.html b/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.2.html index ab9a44c31..2d617f2d5 100644 --- a/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.2.html +++ b/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.2.html @@ -11,6 +11,14 @@ @code { + [Inject] + [NotNull] + private ToastService? ToastService { get; set; } + + [Inject] + [NotNull] + private WebsiteOptions? SiteOptions { get; set; } + private async Task OnClickToUpload(IEnumerable files) { // 示例代码,模拟 80% 几率保存成功 @@ -29,24 +37,33 @@ private CancellationTokenSource? ReadToken { get; set; } private async Task SaveToFile(UploadFile file) { + // Server Side 使用 + // Web Assembly 模式下必须使用 webapi 方式去保存文件到服务器或者数据库中 // 生成写入文件名称 - var uploaderFolder = Path.Combine(WebHost.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); - file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}"; - var fileName = Path.Combine(uploaderFolder, file.FileName); - - ReadCardToken ??= new CancellationTokenSource(); - var ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadCardToken.Token); - - if (ret) + var ret = false; + if (!string.IsNullOrEmpty(SiteOptions.WebRootPath)) { - // 保存成功 - file.PrevUrl = $"images/uploader/{file.FileName}"; + var uploaderFolder = Path.Combine(SiteOptions.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); + file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}"; + var fileName = Path.Combine(uploaderFolder, file.FileName); + + ReadToken ??= new CancellationTokenSource(); + ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadToken.Token); + + if (ret) + { + // 保存成功 + file.PrevUrl = $"images/uploader/{file.FileName}"; + } + else + { + await ToastService.Error("上传文件", $"保存文件失败 {file.OriginFileName}"); + } } else { - await ToastService.Error("上传文件", $"保存文件失败 {file.OriginFileName}"); + await ToastService.Information("保存文件", "当前模式为 WebAssembly 模式,请调用 Webapi 模式保存文件到服务器端或数据库中"); } - return ret; } } diff --git a/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.6.html b/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.6.html index 4128eb6d7..12566bee8 100644 --- a/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.6.html +++ b/src/BootstrapBlazor.Docs/wwwroot/docs/upload/upload.6.html @@ -12,20 +12,39 @@ @code { - private CancellationTokenSource? ReadCardToken { get; set; } + [Inject] + [NotNull] + private ToastService? ToastService { get; set; } + + [Inject] + [NotNull] + private WebsiteOptions? SiteOptions { get; set; } + + private CancellationTokenSource? ReadToken { get; set; } private async Task OnCardUpload(IEnumerable files) { // 示例代码,使用 IWebHostEnviroment 注入获取硬盘文件夹 示例 var file = files.FirstOrDefault(); if (file != null && file.File != null) { - // 生成写入文件名称 - var uploaderFolder = Path.Combine(WebHost.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); + await SaveToFile(file); + } + } + + private async Task SaveToFile(UploadFile file) + { + // Server Side 使用 + // Web Assembly 模式下必须使用 webapi 方式去保存文件到服务器或者数据库中 + // 生成写入文件名称 + var ret = false; + if (!string.IsNullOrEmpty(SiteOptions.WebRootPath)) + { + var uploaderFolder = Path.Combine(SiteOptions.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}"; var fileName = Path.Combine(uploaderFolder, file.FileName); - ReadCardToken ??= new CancellationTokenSource(); - var ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadCardToken.Token); + ReadToken ??= new CancellationTokenSource(); + ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadToken.Token); if (ret) { @@ -37,5 +56,10 @@ await ToastService.Error("上传文件", $"保存文件失败 {file.OriginFileName}"); } } + else + { + await ToastService.Information("保存文件", "当前模式为 WebAssembly 模式,请调用 Webapi 模式保存文件到服务器端或数据库中"); + } + return ret; } } diff --git a/src/BootstrapBlazor.Server/Extensions/TasksExtensions.cs b/src/BootstrapBlazor.Server/Extensions/TasksExtensions.cs index f9ef6ac6b..c6e43c84a 100644 --- a/src/BootstrapBlazor.Server/Extensions/TasksExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/TasksExtensions.cs @@ -29,11 +29,6 @@ namespace Microsoft.Extensions.DependencyInjection services.AddSingleton(); services.AddTaskServices(); services.AddHttpClient(); - services.AddTransient(sp => - { - var factory = sp.GetRequiredService(); - return factory.CreateClient(); - }); services.AddVersionManager(); services.AddExampleService(); services.AddSingleton(); @@ -53,9 +48,11 @@ namespace Microsoft.Extensions.DependencyInjection /// /// /// - public BlazorBackgroundServices(IWebHostEnvironment env) + /// + public BlazorBackgroundServices(IWebHostEnvironment env, WebsiteOptions websiteOption) { _env = env; + websiteOption.WebRootPath = env.WebRootPath; } /// @@ -63,7 +60,7 @@ namespace Microsoft.Extensions.DependencyInjection /// /// /// - protected override Task ExecuteAsync(CancellationToken stoppingToken) => Task.Run(() => + protected override Task ExecuteAsync(CancellationToken stoppingToken) { TaskServicesManager.GetOrAdd("Clear Upload Files", token => { @@ -87,6 +84,8 @@ namespace Microsoft.Extensions.DependencyInjection } return Task.CompletedTask; }, TriggerBuilder.Build(Cron.Minutely(10))); - }); + + return Task.CompletedTask; + } } } diff --git a/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj b/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj index 5e84c6774..205163000 100644 --- a/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj +++ b/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj @@ -22,10 +22,6 @@ - - - - diff --git a/src/BootstrapBlazor.Shared/Extensions/WebsiteOptions.cs b/src/BootstrapBlazor.Shared/Extensions/WebsiteOptions.cs index 90e968e91..d54206e73 100644 --- a/src/BootstrapBlazor.Shared/Extensions/WebsiteOptions.cs +++ b/src/BootstrapBlazor.Shared/Extensions/WebsiteOptions.cs @@ -2,6 +2,8 @@ // 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 System.Diagnostics.CodeAnalysis; + namespace BootstrapBlazor.Shared { /// @@ -28,5 +30,11 @@ namespace BootstrapBlazor.Shared /// /// public string ImageLibUrl { get; set; } = "https://imgs.blazor.zone"; + + /// + /// 获得/设置 系统 wwwroot 文件夹路径 Server Side 模式下 Upload 使用 + /// + [NotNull] + public string? WebRootPath { get; set; } } } diff --git a/src/BootstrapBlazor.Shared/Pages/Uploads.razor.cs b/src/BootstrapBlazor.Shared/Pages/Uploads.razor.cs index dbb42848b..44a195ace 100644 --- a/src/BootstrapBlazor.Shared/Pages/Uploads.razor.cs +++ b/src/BootstrapBlazor.Shared/Pages/Uploads.razor.cs @@ -6,7 +6,7 @@ using BootstrapBlazor.Components; using BootstrapBlazor.Shared.Common; using BootstrapBlazor.Shared.Pages.Components; using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -26,11 +26,11 @@ namespace BootstrapBlazor.Shared.Pages [Inject] [NotNull] - private IWebHostEnvironment? WebHost { get; set; } + private ToastService? ToastService { get; set; } [Inject] [NotNull] - private ToastService? ToastService { get; set; } + private WebsiteOptions? SiteOptions { get; set; } private Logger? Trace { get; set; } @@ -111,24 +111,33 @@ namespace BootstrapBlazor.Shared.Pages private async Task SaveToFile(UploadFile file) { + // Server Side 使用 + // Web Assembly 模式下必须使用 webapi 方式去保存文件到服务器或者数据库中 // 生成写入文件名称 - var uploaderFolder = Path.Combine(WebHost.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); - file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}"; - var fileName = Path.Combine(uploaderFolder, file.FileName); - - ReadToken ??= new CancellationTokenSource(); - var ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadToken.Token); - - if (ret) + var ret = false; + if (!string.IsNullOrEmpty(SiteOptions.WebRootPath)) { - // 保存成功 - file.PrevUrl = $"images/uploader/{file.FileName}"; + var uploaderFolder = Path.Combine(SiteOptions.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader"); + file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}"; + var fileName = Path.Combine(uploaderFolder, file.FileName); + + ReadToken ??= new CancellationTokenSource(); + ret = await file.SaveToFile(fileName, 20 * 1024 * 1024, ReadToken.Token); + + if (ret) + { + // 保存成功 + file.PrevUrl = $"images/uploader/{file.FileName}"; + } + else + { + await ToastService.Error("上传文件", $"保存文件失败 {file.OriginFileName}"); + } } else { - await ToastService.Error("上传文件", $"保存文件失败 {file.OriginFileName}"); + await ToastService.Information("保存文件", "当前模式为 WebAssembly 模式,请调用 Webapi 模式保存文件到服务器端或数据库中"); } - return ret; }