diff --git a/BootstrapBlazor.sln b/BootstrapBlazor.sln index 4608c1c97b2..1ef65d66099 100644 --- a/BootstrapBlazor.sln +++ b/BootstrapBlazor.sln @@ -69,6 +69,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{02EA681E-C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.Shared", "src\BootstrapBlazor.Shared\BootstrapBlazor.Shared.csproj", "{A6E8F478-213E-44EC-BF4D-7C9342C3DEED}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazorAuto", "src\BootstrapBlazorAuto\BootstrapBlazorAuto\BootstrapBlazorAuto.csproj", "{2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazorAuto.Client", "src\BootstrapBlazorAuto\BootstrapBlazorAuto.Client\BootstrapBlazorAuto.Client.csproj", "{7D3FFBD8-A43C-490F-92D1-4F669E7E550F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +111,14 @@ Global {A6E8F478-213E-44EC-BF4D-7C9342C3DEED}.Debug|Any CPU.Build.0 = Debug|Any CPU {A6E8F478-213E-44EC-BF4D-7C9342C3DEED}.Release|Any CPU.ActiveCfg = Release|Any CPU {A6E8F478-213E-44EC-BF4D-7C9342C3DEED}.Release|Any CPU.Build.0 = Release|Any CPU + {2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E}.Release|Any CPU.Build.0 = Release|Any CPU + {7D3FFBD8-A43C-490F-92D1-4F669E7E550F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D3FFBD8-A43C-490F-92D1-4F669E7E550F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D3FFBD8-A43C-490F-92D1-4F669E7E550F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D3FFBD8-A43C-490F-92D1-4F669E7E550F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -123,6 +135,8 @@ Global {D8AEAFE7-10AF-4A5B-BC67-FE740A2CA1DF} = {7C1D79F1-87BC-42C1-BD5A-CDE4044AC1BD} {01DA4687-0973-4CA6-97F5-04E0B8DD1B13} = {7C1D79F1-87BC-42C1-BD5A-CDE4044AC1BD} {A6E8F478-213E-44EC-BF4D-7C9342C3DEED} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE} + {2A69B4F8-7C7D-4AC3-BE13-B862DE078F6E} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE} + {7D3FFBD8-A43C-490F-92D1-4F669E7E550F} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0DCB0756-34FA-4FD0-AE1D-D3F08B5B3A6B} diff --git a/src/BootstrapBlazor.Server/Components/_Imports.razor b/src/BootstrapBlazor.Server/Components/_Imports.razor index 829f3c65d93..6059540e472 100644 --- a/src/BootstrapBlazor.Server/Components/_Imports.razor +++ b/src/BootstrapBlazor.Server/Components/_Imports.razor @@ -1,6 +1,5 @@ @using BootstrapBlazor.Components -@using BootstrapBlazor.Server.Extensions @using BootstrapBlazor.Shared.Components.Components @using BootstrapBlazor.Shared.Components.Layout diff --git a/src/BootstrapBlazor.Server/Controllers/Api/CodeController.cs b/src/BootstrapBlazor.Server/Controllers/Api/CodeController.cs index e9de113f340..7f944b280c5 100644 --- a/src/BootstrapBlazor.Server/Controllers/Api/CodeController.cs +++ b/src/BootstrapBlazor.Server/Controllers/Api/CodeController.cs @@ -8,7 +8,7 @@ using System.Net; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute; -namespace BootstrapBlazor.Server.Controllers.Api; +namespace BootstrapBlazor.Controllers.Api; /// /// diff --git a/src/BootstrapBlazor.Server/Controllers/Api/DispatchController.cs b/src/BootstrapBlazor.Server/Controllers/Api/DispatchController.cs index 720aabd6056..976520144cc 100644 --- a/src/BootstrapBlazor.Server/Controllers/Api/DispatchController.cs +++ b/src/BootstrapBlazor.Server/Controllers/Api/DispatchController.cs @@ -8,7 +8,7 @@ using System.Text; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute; -namespace BootstrapBlazor.Server.Controllers.Api; +namespace BootstrapBlazor.Controllers.Api; /// /// Dispatch 接口 @@ -36,7 +36,7 @@ public IActionResult Get([FromServices] IDispatchService dispatchService, Name = "Reboot" }); } - else if(data == "57D2EADDEC65BE22E104ADB97778E6B0") + else if (data == "57D2EADDEC65BE22E104ADB97778E6B0") { dispatchService.Dispatch(new DispatchEntry() { diff --git a/src/BootstrapBlazor.Server/Controllers/Api/GiteeController.cs b/src/BootstrapBlazor.Server/Controllers/Api/GiteeController.cs index 4d01fda1a24..2c198b4f29b 100644 --- a/src/BootstrapBlazor.Server/Controllers/Api/GiteeController.cs +++ b/src/BootstrapBlazor.Server/Controllers/Api/GiteeController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute; -namespace BootstrapBlazor.Server.Controllers.Api; +namespace BootstrapBlazor.Controllers.Api; /// /// diff --git a/src/BootstrapBlazor.Server/Controllers/Api/LoginController.cs b/src/BootstrapBlazor.Server/Controllers/Api/LoginController.cs index 5c4f0e399e3..81d1f349b12 100644 --- a/src/BootstrapBlazor.Server/Controllers/Api/LoginController.cs +++ b/src/BootstrapBlazor.Server/Controllers/Api/LoginController.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute; -namespace BootstrapBlazor.Server.Controllers.Api; +namespace BootstrapBlazor.Controllers.Api; /// /// 登录控制器 diff --git a/src/BootstrapBlazor.Server/Controllers/CultureController.cs b/src/BootstrapBlazor.Server/Controllers/CultureController.cs index 49da6f17eec..076b7b959f8 100644 --- a/src/BootstrapBlazor.Server/Controllers/CultureController.cs +++ b/src/BootstrapBlazor.Server/Controllers/CultureController.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute; -namespace BootstrapBlazor.Server.Controllers; +namespace BootstrapBlazor.Controllers; /// /// 文化 Controller diff --git a/src/BootstrapBlazor.Server/Controllers/WaterfallController.cs b/src/BootstrapBlazor.Server/Controllers/WaterfallController.cs index d5086486755..0a7250f55ae 100644 --- a/src/BootstrapBlazor.Server/Controllers/WaterfallController.cs +++ b/src/BootstrapBlazor.Server/Controllers/WaterfallController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; -namespace BootstrapBlazor.Server.Controllers; +namespace BootstrapBlazor.Controllers; /// /// 瀑布流控制器 diff --git a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionExtensions.cs b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionExtensions.cs index a393737047c..31f9860f4b2 100644 --- a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone -using BootstrapBlazor.Service.Services; +using Longbow.Tasks.Services; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Options; using System.Text.Encodings.Web; @@ -19,10 +19,7 @@ public static IServiceCollection AddBootstrapBlazorServerService(this IServiceCo services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All)); // 增加错误日志 - services.AddLogging(logBuilder => logBuilder.AddFileLogger()); - - // 增加跨域服务 - services.AddCors(); + services.AddLogging(logging => logging.AddFileLogger()); // 增加多语言支持配置信息 services.AddRequestLocalization>((localizerOption, blazorOption) => @@ -48,18 +45,15 @@ void Invoke(BootstrapBlazorOptions option) #endif services.AddControllers(); - services.AddRazorComponents().AddInteractiveServerComponents(); // 增加 SignalR 服务数据传输大小限制配置 services.Configure(option => option.MaximumReceiveMessageSize = null); - // 增加授权服务 - services.AddAuthorization(); - // 增加后台任务服务 services.AddTaskServices(); services.AddHostedService(); + // 增加通用服务 services.AddBootstrapBlazorServices(); return services; diff --git a/src/BootstrapBlazor.Server/Extensions/StaticFileResponseContextExtensions.cs b/src/BootstrapBlazor.Server/Extensions/StaticFileResponseContextExtensions.cs deleted file mode 100644 index aeeefc6523c..00000000000 --- a/src/BootstrapBlazor.Server/Extensions/StaticFileResponseContextExtensions.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the Apache 2.0 License -// See the LICENSE file in the project root for more information. -// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone - -using Microsoft.AspNetCore.Components.Rendering; -using Microsoft.AspNetCore.StaticFiles; -using Microsoft.Net.Http.Headers; -#if NET9_0_OR_GREATER -using System.Reflection; -#endif - -namespace BootstrapBlazor.Server.Extensions; - -internal static class StaticFileResponseContextExtensions -{ - public static bool IsSupportAssets(this IWebHostEnvironment webHost) - { -#if NET9_0_OR_GREATER - return true; -#else - return false; -#endif - } - - /// - /// - /// - /// - public static RenderFragment RenderAssets(this ComponentBase component) => builder => - { -#if NET9_0_OR_GREATER - var pi = component.GetType().GetProperty("Assets", BindingFlags.Instance | BindingFlags.NonPublic); - if (pi != null) - { - var v = pi.GetValue(component); - if (v is ResourceAssetCollection assets) - { - builder.RenderCss($"{assets["_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css"]}"); - builder.RenderCss($"{assets["_content/BootstrapBlazor.MaterialDesign/css/md.min.css"]}"); - builder.RenderCss($"{assets["_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css"]}"); - builder.RenderCss($"{assets["_content/BootstrapBlazor/css/motronic.min.css"]}"); - builder.RenderCss($"{assets["_content/BootstrapBlazor.Shared/BootstrapBlazor.Shared.bundle.scp.css"]}"); - builder.RenderCss($"{assets["_content/BootstrapBlazor.Shared/css/site.css"]}"); - - builder.OpenComponent(0); - builder.CloseComponent(); - } - } -#endif - }; - - private static void RenderCss(this RenderTreeBuilder builder, string url) - { - builder.OpenElement(0, "link"); - builder.AddAttribute(1, "rel", "stylesheet"); - builder.AddAttribute(2, "href", url); - builder.CloseElement(); - } - - public static void ProcessCache(this StaticFileResponseContext context, IConfiguration configuration) - { - if (context.CanCache(configuration, out var age)) - { - context.Context.Response.Headers[HeaderNames.CacheControl] = $"public, max-age={age}"; - } - } - - private static bool CanCache(this StaticFileResponseContext context, IConfiguration configuration, out int age) - { - var ret = false; - age = 0; - - var fileTypes = configuration.GetFileTypes(); - if (fileTypes.Any(context.CanCache)) - { - ret = true; - age = configuration.GetAge(); - } - return ret; - } - - private static bool CanCache(this StaticFileResponseContext context, string fileType) - { - var ext = Path.GetExtension(context.File.PhysicalPath) ?? ""; - return fileType.Equals(ext, StringComparison.OrdinalIgnoreCase); - } - - private static List? _fileTypes; - private static List GetFileTypes(this IConfiguration configuration) - { - _fileTypes ??= GetFilesFromConfiguration(); - return _fileTypes; - - List GetFilesFromConfiguration() - { - var cacheSection = configuration.GetSection("Cache-Control"); - return cacheSection.GetSection("Files").Get>() ?? []; - } - } - - private static int? _age; - private static int GetAge(this IConfiguration configuration) - { - _age ??= GetAgeFromConfiguration(); - return _age.Value; - - int GetAgeFromConfiguration() - { - var cacheSection = configuration.GetSection("Cache-Control"); - return cacheSection.GetValue("Max-Age", 1000 * 60 * 10); - } - } -} diff --git a/src/BootstrapBlazor.Server/Program.cs b/src/BootstrapBlazor.Server/Program.cs index 42d29b34c1b..d38131ccc9b 100644 --- a/src/BootstrapBlazor.Server/Program.cs +++ b/src/BootstrapBlazor.Server/Program.cs @@ -14,6 +14,9 @@ var builder = WebApplication.CreateBuilder(args); +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + builder.Services.AddBootstrapBlazorServerService(); var app = builder.Build(); @@ -34,11 +37,10 @@ app.UseResponseCompression(); } -#if NET9_0_OR_GREATER +app.UseAntiforgery(); +app.UseBootstrapBlazor(); + app.MapStaticAssets(); -#else -app.UseStaticFiles(); -#endif var cors = app.Configuration["AllowOrigins"]?.Split(',', StringSplitOptions.RemoveEmptyEntries); if (cors?.Length > 0) @@ -49,10 +51,9 @@ .AllowCredentials()); } -app.UseBootstrapBlazor(); -app.UseAntiforgery(); - app.MapDefaultControllerRoute(); -app.MapRazorComponents().AddInteractiveServerRenderMode().AddAdditionalAssemblies(typeof(MainLayout).Assembly); +app.MapRazorComponents() + .AddInteractiveServerRenderMode() + .AddAdditionalAssemblies(typeof(MainLayout).Assembly); app.Run(); diff --git a/src/BootstrapBlazor.Server/Services/ClearUploadFilesService.cs b/src/BootstrapBlazor.Server/Services/ClearUploadFilesService.cs index b0ff7e62891..18f49f557f8 100644 --- a/src/BootstrapBlazor.Server/Services/ClearUploadFilesService.cs +++ b/src/BootstrapBlazor.Server/Services/ClearUploadFilesService.cs @@ -3,9 +3,7 @@ // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone -using Longbow.Tasks; - -namespace BootstrapBlazor.Service.Services; +namespace Longbow.Tasks.Services; /// /// 后台任务服务类 diff --git a/src/BootstrapBlazor.Server/appsettings.Development.json b/src/BootstrapBlazor.Server/appsettings.Development.json index f57da39186c..8f81fbe4fa3 100644 --- a/src/BootstrapBlazor.Server/appsettings.Development.json +++ b/src/BootstrapBlazor.Server/appsettings.Development.json @@ -6,25 +6,8 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowOrigins": "http://localhost:5000", - "SassCompiler": { - "SourceFolder": "Styles", - "TargetFolder": "wwwroot/css", - "Arguments": "--style=compressed", - "GenerateScopedCss": true, - "ScopedCssFolders": [ "Views", "Pages", "Shared", "Components" ], - "IncludePaths": [], - - // You can override specific options based on the build configuration - "Configurations": { - "Debug": { // These options apply only to Debug builds - "Arguments": "--style=expanded" - } - } - }, "WebsiteOptions": { - "ServerUrl": "http://localhost:5053", - "WasmUrl": "http://localhost:5055" + "ServerUrl": "http://localhost:5053" }, "BootstrapBlazorOptions": { "ToastDelay": 4000, @@ -52,17 +35,5 @@ "OnTouchDelay": 600 } }, - "GiteeOptions": { - "ClientId": "", - "ClientSecret": "", - "CallbackPath": "/", - "Scope": "" - }, - "GitHubOptions": { - "ClientId": "", - "ClientSecret": "", - "CallbackPath": "/", - "Scope": "" - }, "SupportedLanguages": [ "zh-CN", "ru-RU" ] } diff --git a/src/BootstrapBlazor.Server/appsettings.json b/src/BootstrapBlazor.Server/appsettings.json index ddd8f5f59b4..e4f5a4d51b9 100644 --- a/src/BootstrapBlazor.Server/appsettings.json +++ b/src/BootstrapBlazor.Server/appsettings.json @@ -13,7 +13,7 @@ } }, "AllowedHosts": "*", - "AllowOrigins": "http://localhost:50855,http://wasm.blazor.zone,https://wasm.blazor.zone", + "AllowOrigins": "", "ConnectionStrings": { "bb": "Data Source=bb.db;" }, diff --git a/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj b/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj index afe7e0ebcfc..b8bc61bfcb6 100644 --- a/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj +++ b/src/BootstrapBlazor.Shared/BootstrapBlazor.Shared.csproj @@ -14,10 +14,6 @@ - - - - diff --git a/src/BootstrapBlazor.Shared/Components/Components/CultureChooser.razor.cs b/src/BootstrapBlazor.Shared/Components/Components/CultureChooser.razor.cs index 52c8ff9fd8c..056aebd50cc 100644 --- a/src/BootstrapBlazor.Shared/Components/Components/CultureChooser.razor.cs +++ b/src/BootstrapBlazor.Shared/Components/Components/CultureChooser.razor.cs @@ -4,6 +4,7 @@ // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone using Microsoft.Extensions.Options; +using Microsoft.JSInterop; using System.Globalization; namespace BootstrapBlazor.Shared.Components.Components; @@ -19,7 +20,7 @@ public partial class CultureChooser [Inject] [NotNull] - private IOptionsMonitor? WebsiteOption { get; set; } + private IJSRuntime? JSRuntime { get; set; } [Inject] [NotNull] @@ -33,7 +34,7 @@ public partial class CultureChooser .AddClassFromAttributes(AdditionalAttributes) .Build(); - private string SelectedCulture { get; set; } = CultureInfo.CurrentUICulture.Name; + private string SelectedCulture { get; set; } = CultureInfo.CurrentCulture.Name; [NotNull] private string? Label { get; set; } @@ -50,38 +51,39 @@ protected override void OnInitialized() private async Task SetCulture(SelectedItem item) { - if (OperatingSystem.IsBrowser()) + if (RendererInfo.Name == "Server") { - var cultureName = item.Value; - if (cultureName != CultureInfo.CurrentCulture.Name) + // 使用 api 方式 适用于 Server-Side 模式 + if (SelectedCulture != item.Value) { - await JSRuntime.SetCulture(cultureName); - var culture = new CultureInfo(cultureName); - CultureInfo.CurrentCulture = culture; - CultureInfo.CurrentUICulture = culture; + var culture = item.Value; + var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped); + var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={Uri.EscapeDataString(uri)}"; - NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + // use a path that matches your culture redirect controller from the previous steps + NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true); } } else { - // 使用 api 方式 适用于 Server-Side 模式 if (SelectedCulture != item.Value) { var culture = item.Value; - var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped); - var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={Uri.EscapeDataString(uri)}"; + await JSRuntime.InvokeVoidAsync("bbCulture.set", culture); - // use a path that matches your culture redirect controller from the previous steps - NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true); + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } } } - private static string GetDisplayName(CultureInfo culture) + private string GetDisplayName(CultureInfo culture) { string? ret; - if (OperatingSystem.IsBrowser()) + if (RendererInfo.Name == "Server") + { + ret = culture.NativeName; + } + else { ret = culture.Name switch { @@ -90,10 +92,6 @@ private static string GetDisplayName(CultureInfo culture) _ => "" }; } - else - { - ret = culture.NativeName; - } return ret; } } diff --git a/src/BootstrapBlazor.Shared/Extensions/JSRuntimeExtensions.cs b/src/BootstrapBlazor.Shared/Extensions/JSRuntimeExtensions.cs deleted file mode 100644 index d51bc51daba..00000000000 --- a/src/BootstrapBlazor.Shared/Extensions/JSRuntimeExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the Apache 2.0 License -// See the LICENSE file in the project root for more information. -// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone - -using Microsoft.JSInterop; - -namespace BootstrapBlazor.Shared.Extensions; - -/// -/// -/// -public static class JSRuntimeExtensions -{ - /// - /// - /// - /// - /// - public static ValueTask SetCulture(this IJSRuntime jsRuntime, string cultureName) => jsRuntime.InvokeVoidAsync("BB.blazorCulture.set", cultureName); - - /// - /// - /// - /// - public static ValueTask GetCulture(this IJSRuntime jsRuntime) => jsRuntime.InvokeAsync("BB.blazorCulture.get"); -} diff --git a/src/BootstrapBlazor.Shared/Extensions/ServicesCollectionExtensions.cs b/src/BootstrapBlazor.Shared/Extensions/ServicesCollectionExtensions.cs index e20367118e2..a224715fff3 100644 --- a/src/BootstrapBlazor.Shared/Extensions/ServicesCollectionExtensions.cs +++ b/src/BootstrapBlazor.Shared/Extensions/ServicesCollectionExtensions.cs @@ -4,7 +4,6 @@ // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection; @@ -20,8 +19,26 @@ public static class ServicesCollectionExtensions /// public static IServiceCollection AddBootstrapBlazorServices(this IServiceCollection services, Action? configureOptions = null) { - // 增加演示网站服务 - services.AddWebSiteServices(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(typeof(IDataService<>), typeof(TableDemoDataService<>)); + services.AddSingleton(); + services.AddSingleton(); + + services.AddSingleton(); + services.AddScoped(); + + // 增加示例网站配置 + services.AddOptionsMonitor(); + + // 增加模拟登录服务 + services.AddCascadingAuthenticationState(); + services.AddScoped(); + + // 增加 MeiliSearch 服务 + services.AddBootstrapBlazorMeiliSearch(); // 增加 BootstrapBlazor 组件 services.AddBootstrapBlazor(configureOptions); @@ -107,34 +124,4 @@ public static IServiceCollection AddBootstrapBlazorServices(this IServiceCollect //}); return services; } - - /// - /// 添加 Server Side 演示网站服务 - /// - /// - public static IServiceCollection AddWebSiteServices(this IServiceCollection services) - { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(typeof(IDataService<>), typeof(TableDemoDataService<>)); - services.AddSingleton(typeof(ILookupService), typeof(DemoLookupService)); - services.AddSingleton(); - - services.AddSingleton(); - services.AddScoped(); - - // 增加示例网站配置 - services.AddOptionsMonitor(); - - // 增加模拟登录服务 - services.AddCascadingAuthenticationState(); - services.AddScoped(); - - // 增加 MeiliSearch 服务 - services.AddBootstrapBlazorMeiliSearch(); - - return services; - } } diff --git a/src/BootstrapBlazor.Shared/Services/DashboardService.cs b/src/BootstrapBlazor.Shared/Services/DashboardService.cs index a37586afcad..306e33cf9b0 100644 --- a/src/BootstrapBlazor.Shared/Services/DashboardService.cs +++ b/src/BootstrapBlazor.Shared/Services/DashboardService.cs @@ -12,7 +12,7 @@ namespace BootstrapBlazor.Shared.Services; /// class DashboardService { - private static readonly Random _random = new(); + private static readonly Random _random = Random.Shared; /// /// 获取仪表盘数据 diff --git a/src/BootstrapBlazorAuto/.gitignore b/src/BootstrapBlazorAuto/.gitignore new file mode 100644 index 00000000000..87fbbc492bf --- /dev/null +++ b/src/BootstrapBlazorAuto/.gitignore @@ -0,0 +1,2 @@ +**/appsettings*.json +**/wwwroot/favicon.* diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/BootstrapBlazorAuto.Client.csproj b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/BootstrapBlazorAuto.Client.csproj new file mode 100644 index 00000000000..acd445f8229 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/BootstrapBlazorAuto.Client.csproj @@ -0,0 +1,19 @@ + + + + true + Default + true + + + + + + + + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.props b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.props new file mode 100644 index 00000000000..fc268bd2af6 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.targets b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.targets new file mode 100644 index 00000000000..a81952d35dd --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Directory.Build.targets @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Program.cs b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Program.cs new file mode 100644 index 00000000000..60ed6e84036 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Program.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.JSInterop; +using System.Globalization; + +var builder = WebAssemblyHostBuilder.CreateDefault(args); + +builder.Services.AddBootstrapBlazorServices(); + +var host = builder.Build(); + +const string defaultCulture = "en-US"; + +var js = host.Services.GetRequiredService(); +var result = await js.InvokeAsync("bbCulture.get"); +var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture); + +if (result == null) +{ + await js.InvokeVoidAsync("bbCulture.set", defaultCulture); +} + +CultureInfo.DefaultThreadCurrentCulture = culture; +CultureInfo.DefaultThreadCurrentUICulture = culture; + +await host.RunAsync(); diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Routes.razor b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Routes.razor new file mode 100644 index 00000000000..242e0fffc98 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/Routes.razor @@ -0,0 +1,5 @@ + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/_Imports.razor b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/_Imports.razor new file mode 100644 index 00000000000..fd1d8c4f67e --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto.Client/_Imports.razor @@ -0,0 +1,10 @@ +@using BootstrapBlazor.Components +@using BootstrapBlazor.Shared.Components.Layout +@using BootstrapBlazorAuto.Client + +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web + +@using System.Net.Http +@using System.Net.Http.Json diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/BootstrapBlazorAuto.csproj b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/BootstrapBlazorAuto.csproj new file mode 100644 index 00000000000..5d9e34cb4ab --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/BootstrapBlazorAuto.csproj @@ -0,0 +1,36 @@ + + + + net9.0 + dd866c36-9a9b-4dda-bce0-44c91d3094cc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/App.razor b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/App.razor new file mode 100644 index 00000000000..0bbc7af707c --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/App.razor @@ -0,0 +1,69 @@ +@inject IWebHostEnvironment Env +@inject IStringLocalizer Localizer +@inject IOptions WebsiteOption + + + + + + + + + + + + + @Localizer["SiteTitle"] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @if (Env.IsProduction()) + { + + + + } + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/Pages/Error.razor b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/Pages/Error.razor new file mode 100644 index 00000000000..576cc2d2f4d --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/Pages/Error.razor @@ -0,0 +1,36 @@ +@page "/Error" +@using System.Diagnostics + +Error + +

Error.

+

An error occurred while processing your request.

+ +@if (ShowRequestId) +{ +

+ Request ID: @RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+ +@code{ + [CascadingParameter] + private HttpContext? HttpContext { get; set; } + + private string? RequestId { get; set; } + private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + protected override void OnInitialized() => + RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; +} diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/_Imports.razor b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/_Imports.razor new file mode 100644 index 00000000000..5c8b8ce2eac --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Components/_Imports.razor @@ -0,0 +1,21 @@ +@using BootstrapBlazor.Components + +@using BootstrapBlazorAuto +@using BootstrapBlazorAuto.Client +@using BootstrapBlazorAuto.Components + +@using BootstrapBlazor.Shared.Components.Components +@using BootstrapBlazor.Shared.Components.Layout +@using BootstrapBlazor.Shared.Data + +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.Localization +@using Microsoft.Extensions.Options +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop + +@using System.Net.Http +@using System.Net.Http.Json diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.props b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.props new file mode 100644 index 00000000000..fc268bd2af6 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.targets b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.targets new file mode 100644 index 00000000000..e539458b9f0 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Directory.Build.targets @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Program.cs b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Program.cs new file mode 100644 index 00000000000..f91833b342a --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Program.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +using BootstrapBlazor.Shared.Components.Layout; +using BootstrapBlazorAuto.Components; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents() + .AddInteractiveWebAssemblyComponents(); + +builder.Services.AddBootstrapBlazorServerService(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseWebAssemblyDebugging(); +} +else +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); +} + +app.UseAntiforgery(); +app.UseBootstrapBlazor(); + +app.MapStaticAssets(); +app.MapDefaultControllerRoute(); +app.MapRazorComponents() + .AddInteractiveServerRenderMode() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(typeof(MainLayout).Assembly); + +app.Run(); diff --git a/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Properties/launchSettings.json b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Properties/launchSettings.json new file mode 100644 index 00000000000..d6574bbcb81 --- /dev/null +++ b/src/BootstrapBlazorAuto/BootstrapBlazorAuto/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5220", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } + }