diff --git a/Directory.Packages.props b/Directory.Packages.props index ff913ef39..0c63154f9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -64,5 +64,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/GrandNode.sln b/GrandNode.sln index 1c8ca9b46..964782589 100644 --- a/GrandNode.sln +++ b/GrandNode.sln @@ -137,6 +137,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grand.Module.Api", "src\Mod EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grand.Module.ScheduledTasks", "src\Modules\Grand.Module.ScheduledTasks\Grand.Module.ScheduledTasks.csproj", "{136F1E35-8B20-465C-8D42-30A5A0D0DA1F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.AppHost", "src\Aspire\Aspire.AppHost\Aspire.AppHost.csproj", "{FFA85947-690E-496B-B21E-DB1800F0DCA9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.ServiceDefaults", "src\Aspire\Aspire.ServiceDefaults\Aspire.ServiceDefaults.csproj", "{591950E4-6377-4ECA-A386-8BD3FFE302F1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -363,6 +367,14 @@ Global {136F1E35-8B20-465C-8D42-30A5A0D0DA1F}.Debug|Any CPU.Build.0 = Debug|Any CPU {136F1E35-8B20-465C-8D42-30A5A0D0DA1F}.Release|Any CPU.ActiveCfg = Release|Any CPU {136F1E35-8B20-465C-8D42-30A5A0D0DA1F}.Release|Any CPU.Build.0 = Release|Any CPU + {FFA85947-690E-496B-B21E-DB1800F0DCA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFA85947-690E-496B-B21E-DB1800F0DCA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFA85947-690E-496B-B21E-DB1800F0DCA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFA85947-690E-496B-B21E-DB1800F0DCA9}.Release|Any CPU.Build.0 = Release|Any CPU + {591950E4-6377-4ECA-A386-8BD3FFE302F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {591950E4-6377-4ECA-A386-8BD3FFE302F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {591950E4-6377-4ECA-A386-8BD3FFE302F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {591950E4-6377-4ECA-A386-8BD3FFE302F1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj b/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj new file mode 100644 index 000000000..b3a26a60f --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj @@ -0,0 +1,23 @@ + + + + + + Exe + net9.0 + enable + enable + true + bdc1e5b4-4475-44fc-851c-dd576ac2c123 + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.AppHost/Program.cs b/src/Aspire/Aspire.AppHost/Program.cs new file mode 100644 index 000000000..5a1daa4a6 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Program.cs @@ -0,0 +1,17 @@ + +var builder = DistributedApplication.CreateBuilder(args); + + +var mongo = builder.AddMongoDB("mongo") + .WithLifetime(ContainerLifetime.Persistent); + +var mongodb = mongo.AddDatabase("Mongodb"); + +builder + .AddProject("grand-web") + .WithHttpEndpoint(80) + .WithEnvironment("", "") + .WithReference(mongodb) + .WaitFor(mongodb); + +builder.Build().Run(); diff --git a/src/Aspire/Aspire.AppHost/Properties/launchSettings.json b/src/Aspire/Aspire.AppHost/Properties/launchSettings.json new file mode 100644 index 000000000..43ec3ebbe --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Properties/launchSettings.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:17196;http://localhost:15129", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21225", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22257", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + } + }, + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15129", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19032", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20163", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + + } + } + } +} diff --git a/src/Aspire/Aspire.AppHost/appsettings.Development.json b/src/Aspire/Aspire.AppHost/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.AppHost/appsettings.json b/src/Aspire/Aspire.AppHost/appsettings.json new file mode 100644 index 000000000..31c092aa4 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj b/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj new file mode 100644 index 000000000..f6cb4c09d --- /dev/null +++ b/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj @@ -0,0 +1,22 @@ + + + + net9.0 + enable + enable + true + + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.ServiceDefaults/Extensions.cs b/src/Aspire/Aspire.ServiceDefaults/Extensions.cs new file mode 100644 index 000000000..d5cfd5122 --- /dev/null +++ b/src/Aspire/Aspire.ServiceDefaults/Extensions.cs @@ -0,0 +1,89 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.ServiceDiscovery; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// This project should be referenced by each service project in your solution. +// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults +public static class Extensions +{ + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + builder.ConfigureOpenTelemetry(); + + builder.Services.AddServiceDiscovery(); + + builder.Services.ConfigureHttpClientDefaults(http => + { + // Turn on resilience by default + http.AddStandardResilienceHandler(); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + // Uncomment the following to restrict the allowed schemes for service discovery. + // builder.Services.Configure(options => + // { + // options.AllowedSchemes = ["https"]; + // }); + + return builder; + } + + public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation(); + }) + .WithTracing(tracing => + { + tracing.AddSource(builder.Environment.ApplicationName) + .AddAspNetCoreInstrumentation() + // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) + //.AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + + return builder; + } + + private static TBuilder AddOpenTelemetryExporters(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + if (useOtlpExporter) + { + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + } + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package) + //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"])) + //{ + // builder.Services.AddOpenTelemetry() + // .UseAzureMonitor(); + //} + + return builder; + } +} diff --git a/src/Core/Grand.Infrastructure/Configuration/DatabaseConfig.cs b/src/Core/Grand.Infrastructure/Configuration/DatabaseConfig.cs index c2396e529..6bb260554 100644 --- a/src/Core/Grand.Infrastructure/Configuration/DatabaseConfig.cs +++ b/src/Core/Grand.Infrastructure/Configuration/DatabaseConfig.cs @@ -16,11 +16,4 @@ public class DatabaseConfig /// Gets or sets a value indicating whether use LiteDB database (only for installation process) /// public string LiteDbConnectionString { get; set; } - - /// - /// Gets or sets a value indicating whether use connection string for database (only for installed databases) - /// - public string ConnectionString { get; set; } - - public int DbProvider { get; set; } } \ No newline at end of file diff --git a/src/Core/Grand.Infrastructure/Configuration/PerformanceConfig.cs b/src/Core/Grand.Infrastructure/Configuration/PerformanceConfig.cs index 6597c5aac..b95260ea8 100644 --- a/src/Core/Grand.Infrastructure/Configuration/PerformanceConfig.cs +++ b/src/Core/Grand.Infrastructure/Configuration/PerformanceConfig.cs @@ -10,11 +10,6 @@ public class PerformanceConfig /// public bool UseResponseCompression { get; set; } - /// - /// Gets or sets a value indicating whether ignore DbVersionCheckMiddleware - /// - public bool IgnoreDbVersionCheckMiddleware { get; set; } - /// /// Gets or sets a value indicating whether ignore IgnoreUsePoweredByMiddleware /// diff --git a/src/Core/Grand.Infrastructure/StartupBase.cs b/src/Core/Grand.Infrastructure/StartupBase.cs index 70e0d350a..8d05f49f7 100644 --- a/src/Core/Grand.Infrastructure/StartupBase.cs +++ b/src/Core/Grand.Infrastructure/StartupBase.cs @@ -36,11 +36,18 @@ public static class StartupBase /// private static void InitDatabase(IServiceCollection services, IConfiguration configuration) { - var dbConfig = services.StartupConfig(configuration.GetSection("Database")); - if (!string.IsNullOrEmpty(dbConfig.ConnectionString)) + var connectionString = configuration["ConnectionStrings:Mongodb"]; + var providerString = configuration["ConnectionStrings:Provider"]; + var providerInt = 0; + if (!string.IsNullOrEmpty(providerString)) + { + _ = int.TryParse(providerString, out providerInt); + } + + if (!string.IsNullOrEmpty(connectionString)) DataSettingsManager.Instance.LoadDataSettings(new DataSettings { - ConnectionString = dbConfig.ConnectionString, - DbProvider = (DbProvider)dbConfig.DbProvider + ConnectionString = connectionString, + DbProvider = (DbProvider)providerInt, }); } diff --git a/src/Modules/Grand.Module.Installer/Controllers/InstallController.cs b/src/Modules/Grand.Module.Installer/Controllers/InstallController.cs index 5ab7da3b6..32de67750 100644 --- a/src/Modules/Grand.Module.Installer/Controllers/InstallController.cs +++ b/src/Modules/Grand.Module.Installer/Controllers/InstallController.cs @@ -2,13 +2,13 @@ using Grand.Infrastructure.Caching; using Grand.Infrastructure.Configuration; using Grand.Infrastructure.Plugins; -using Grand.Module.Installer.Filters; using Grand.Module.Installer.Interfaces; using Grand.Module.Installer.Models; using Grand.SharedKernel.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -16,7 +16,6 @@ namespace Grand.Module.Installer.Controllers; -[DatabaseConfigured] public class InstallController : Controller { @@ -25,6 +24,7 @@ public class InstallController : Controller private readonly ICacheBase _cacheBase; private readonly IHostApplicationLifetime _applicationLifetime; private readonly DatabaseConfig _dbConfig; + private readonly IConfiguration _configuration; private readonly ILogger _logger; /// @@ -40,11 +40,13 @@ public InstallController( ICacheBase cacheBase, IHostApplicationLifetime applicationLifetime, DatabaseConfig dbConfig, + IConfiguration configuration, ILogger logger) { _cacheBase = cacheBase; _applicationLifetime = applicationLifetime; _dbConfig = dbConfig; + _configuration = configuration; _logger = logger; } @@ -70,9 +72,10 @@ private InstallModel PrepareModel(InstallModel? model) model ??= new InstallModel { AdminEmail = "admin@yourstore.com", InstallSampleData = false, - DatabaseConnectionString = "", AdminPassword = "", - ConfirmPassword = "" + ConfirmPassword = "", + DatabaseConnectionString = _configuration["ConnectionStrings:Mongodb"], + ConnectionInfo = !string.IsNullOrEmpty(_configuration["ConnectionStrings:Mongodb"]), }; model.AvailableProviders = Enum.GetValues(typeof(DbProvider)).Cast().Select(v => new SelectListItem { diff --git a/src/Modules/Grand.Module.Installer/Filters/DatabaseConfiguredAttribute.cs b/src/Modules/Grand.Module.Installer/Filters/DatabaseConfiguredAttribute.cs deleted file mode 100644 index d4319211c..000000000 --- a/src/Modules/Grand.Module.Installer/Filters/DatabaseConfiguredAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Grand.Data; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; - -namespace Grand.Module.Installer.Filters; - -public class DatabaseConfiguredAttribute : Attribute, IAsyncActionFilter -{ - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - if (!DataSettingsManager.DatabaseIsInstalled()) - { - await next(); - } - else - { - context.Result = new NotFoundResult(); - } - } -} diff --git a/src/Modules/Grand.Module.Installer/Startup/EndpointProvider.cs b/src/Modules/Grand.Module.Installer/Startup/EndpointProvider.cs new file mode 100644 index 000000000..9cbe4d7f7 --- /dev/null +++ b/src/Modules/Grand.Module.Installer/Startup/EndpointProvider.cs @@ -0,0 +1,15 @@ +using Grand.Infrastructure.Endpoints; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; + +namespace Grand.Module.Installer.Startup; + +public class EndpointProvider : IEndpointProvider +{ + public int Priority => int.MinValue; + + public void RegisterEndpoint(IEndpointRouteBuilder endpointRouteBuilder) + { + endpointRouteBuilder.MapControllerRoute("Install", "install", new { controller = "Install", action = "Index" }); + } +} diff --git a/src/Modules/Grand.Module.Installer/Startup/StartupApplication.cs b/src/Modules/Grand.Module.Installer/Startup/StartupApplication.cs index 132744ee9..94a44092a 100644 --- a/src/Modules/Grand.Module.Installer/Startup/StartupApplication.cs +++ b/src/Modules/Grand.Module.Installer/Startup/StartupApplication.cs @@ -1,5 +1,4 @@ -using Grand.Data; -using Grand.Infrastructure; +using Grand.Infrastructure; using Grand.Module.Installer.Interfaces; using Grand.Module.Installer.Services; using Microsoft.AspNetCore.Builder; @@ -25,13 +24,8 @@ public void Configure(WebApplication application, IWebHostEnvironment webHostEnv private void RegisterInstallService(IServiceCollection serviceCollection) { - var databaseInstalled = DataSettingsManager.DatabaseIsInstalled(); - if (!databaseInstalled) - { - //installation service - serviceCollection.AddScoped(); - serviceCollection.AddScoped(); - serviceCollection.AddTransient(); - } + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddTransient(); } } \ No newline at end of file diff --git a/src/Modules/Grand.Module.Migration/Migrations/MigrationProcess.cs b/src/Modules/Grand.Module.Migration/Migrations/MigrationProcess.cs index 145c023e4..dfe9c79bd 100644 --- a/src/Modules/Grand.Module.Migration/Migrations/MigrationProcess.cs +++ b/src/Modules/Grand.Module.Migration/Migrations/MigrationProcess.cs @@ -57,6 +57,8 @@ public virtual void RunMigrationProcess() { var migrationsDb = GetMigrationDb(); var version = _repositoryVersion.Table.FirstOrDefault(); + if(version == null) + return; var majorVersion = string.IsNullOrEmpty(version?.InstalledVersion) ? int.Parse(version?.DataBaseVersion.Split('.')[0]!) : int.Parse(version?.InstalledVersion.Split('.')[0]!); var minorVersion = string.IsNullOrEmpty(version?.InstalledVersion) ? int.Parse(version?.DataBaseVersion.Split('.')[1]!) : int.Parse(version?.InstalledVersion.Split('.')[1]!); var migrationManager = new MigrationManager(); diff --git a/src/Web/Grand.Web.Common/Middleware/DbVersionCheckMiddleware.cs b/src/Web/Grand.Web.Common/Middleware/DbVersionCheckMiddleware.cs deleted file mode 100644 index 1913628b6..000000000 --- a/src/Web/Grand.Web.Common/Middleware/DbVersionCheckMiddleware.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Grand.Data; -using Grand.Domain.Common; -using Grand.Infrastructure; -using Grand.Infrastructure.Caching; -using Grand.Infrastructure.Caching.Constants; -using Microsoft.AspNetCore.Http; - -namespace Grand.Web.Common.Middleware; - -public class DbVersionCheckMiddleware -{ - private readonly RequestDelegate _next; - - public DbVersionCheckMiddleware(RequestDelegate next) - { - _next = next; - } - - public async Task Invoke( - HttpContext context, - ICacheBase cacheBase, - IRepository repository) - { - if (context?.Request == null) return; - - var version = cacheBase.Get(CacheKey.GRAND_NODE_VERSION, () => repository.Table.FirstOrDefault()); - if (version == null) - { - await context.Response.WriteAsync("The database does not exist."); - return; - } - - if (!version.DataBaseVersion.Equals(GrandVersion.SupportedDBVersion)) - await context.Response.WriteAsync("The database version is not supported in this software version. " + - $"Supported version: {GrandVersion.SupportedDBVersion} , your version: {version.DataBaseVersion}"); - else - await _next(context); - } -} \ No newline at end of file diff --git a/src/Web/Grand.Web.Common/Middleware/InstallUrlMiddleware.cs b/src/Web/Grand.Web.Common/Middleware/InstallUrlMiddleware.cs index 16fc3d7db..13552c30f 100644 --- a/src/Web/Grand.Web.Common/Middleware/InstallUrlMiddleware.cs +++ b/src/Web/Grand.Web.Common/Middleware/InstallUrlMiddleware.cs @@ -1,4 +1,10 @@ -using Grand.Data; +#nullable enable + +using Grand.Data; +using Grand.Domain.Common; +using Grand.Infrastructure; +using Grand.Infrastructure.Caching; +using Grand.Infrastructure.Caching.Constants; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.DependencyInjection; @@ -11,52 +17,86 @@ public class InstallUrlMiddleware #region Fields private readonly RequestDelegate _next; + private readonly ICacheBase _cacheBase; + private const string InstallUrl = "/install"; #endregion #region Ctor - public InstallUrlMiddleware(RequestDelegate next) + public InstallUrlMiddleware(RequestDelegate next, ICacheBase cacheBase) { _next = next; + _cacheBase = cacheBase; } #endregion #region Methods - /// - /// Invoke middleware actions - /// - /// HTTP context - /// Task public async Task InvokeAsync(HttpContext context) { - //whether database is installed if (!DataSettingsManager.DatabaseIsInstalled()) { - var featureManager = context.RequestServices.GetRequiredService(); - var isInstallerModuleEnabled = await featureManager.IsEnabledAsync("Grand.Module.Installer"); - if (!isInstallerModuleEnabled) - { - // Return a response indicating the installer module is not enabled - context.Response.StatusCode = StatusCodes.Status403Forbidden; - await context.Response.WriteAsync("The installation module is not enabled."); - return; - } - - const string installUrl = "/install"; - if (!context.Request.GetEncodedPathAndQuery().StartsWith(installUrl, StringComparison.OrdinalIgnoreCase)) - { - //redirect - context.Response.Redirect(installUrl); - return; - } + await HandleInstallationAsync(context); + return; + } + + var version = GetDatabaseVersion(context); + + if (version == null) + { + await HandleInstallationAsync(context); + return; + } + + if (!version.DataBaseVersion.Equals(GrandVersion.SupportedDBVersion)) + { + await context.Response.WriteAsync($"The database version is not supported in this software version. Supported version: {GrandVersion.SupportedDBVersion}, your version: {version.DataBaseVersion}"); + return; + } + + if (IsInstallUrl(context.Request)) + { + context.Response.Redirect("/"); + return; } - //or call the next middleware in the request pipeline + // Call the next middleware in the pipeline await _next(context); } + private async Task HandleInstallationAsync(HttpContext context) + { + var featureManager = context.RequestServices.GetRequiredService(); + var isInstallerModuleEnabled = await featureManager.IsEnabledAsync("Grand.Module.Installer"); + + if (!isInstallerModuleEnabled) + { + context.Response.StatusCode = StatusCodes.Status403Forbidden; + await context.Response.WriteAsync("The installation module is not enabled."); + return; + } + + if (!IsInstallUrl(context.Request)) + { + context.Response.Redirect(InstallUrl); + } + } + + private GrandNodeVersion? GetDatabaseVersion(HttpContext context) + { + return _cacheBase.Get(CacheKey.GRAND_NODE_VERSION, () => + { + var repository = context.RequestServices.GetRequiredService>(); + return repository.Table.FirstOrDefault(); + }, int.MaxValue); + } + + private bool IsInstallUrl(HttpRequest request) + { + return request.GetEncodedPathAndQuery().StartsWith(InstallUrl, StringComparison.OrdinalIgnoreCase); + } + #endregion -} \ No newline at end of file +} diff --git a/src/Web/Grand.Web.Common/Middleware/WorkContextMiddleware.cs b/src/Web/Grand.Web.Common/Middleware/WorkContextMiddleware.cs index ea200818b..06750a594 100644 --- a/src/Web/Grand.Web.Common/Middleware/WorkContextMiddleware.cs +++ b/src/Web/Grand.Web.Common/Middleware/WorkContextMiddleware.cs @@ -10,7 +10,7 @@ public class WorkContextMiddleware private readonly RequestDelegate _next; - private readonly List skipRoutePattern = ["/scalar/{documentName}", "/openapi/{documentName}.json"]; + private readonly List skipRoutePattern = ["/scalar/{documentName}", "/openapi/{documentName}.json", "install"]; #endregion diff --git a/src/Web/Grand.Web.Common/Startup/DbCheckStartup.cs b/src/Web/Grand.Web.Common/Startup/DbCheckStartup.cs deleted file mode 100644 index d14c22645..000000000 --- a/src/Web/Grand.Web.Common/Startup/DbCheckStartup.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Grand.Data; -using Grand.Infrastructure; -using Grand.Infrastructure.Configuration; -using Grand.Web.Common.Middleware; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; - -namespace Grand.Web.Common.Startup; - -public class DbCheckStartup : IStartupApplication -{ - public int Priority => 0; - public bool BeforeConfigure => false; - - public void Configure(WebApplication application, IWebHostEnvironment webHostEnvironment) - { - if (!DataSettingsManager.DatabaseIsInstalled()) - return; - - var performanceConfig = application.Services.GetRequiredService(); - - if (!performanceConfig.IgnoreDbVersionCheckMiddleware) - application.UseMiddleware(); - } - - public void ConfigureServices(IServiceCollection services, IConfiguration configuration) - { - } -} \ No newline at end of file diff --git a/src/Web/Grand.Web/App_Data/appsettings.json b/src/Web/Grand.Web/App_Data/appsettings.json index c46438c4b..8beaa9493 100644 --- a/src/Web/Grand.Web/App_Data/appsettings.json +++ b/src/Web/Grand.Web/App_Data/appsettings.json @@ -21,16 +21,17 @@ //Gets or sets the value to enable a middleware for logging additional information about CurrentCustomer and CurrentStore "EnableContextLoggingMiddleware": true }, + //only for advanced users, allow to set ConnectionString for MongoDb + "ConnectionStrings": { + "Mongodb": "" + }, "Database": { //This setting is required to use LiteDB database "UseLiteDb": false, //LiteDB database as a singleton service in the application "Singleton": true, //Init connection string - it's required only for the installation process! - "LiteDbConnectionString": "Filename=App_Data/database.db", - //only for advanced users, allow to set ConnectionString for MongoDb - "ConnectionString": "", - "DbProvider": 0 + "LiteDbConnectionString": "Filename=App_Data/database.db" }, "Security": { //Use a reverse proxy server - more information you can find at: https://docs.microsoft.com/en-US/aspnet/core/host-and-deploy/linux-nginx @@ -104,8 +105,6 @@ //Indicates whether to compress response (gzip by default) //You may want to disable it, for example, If you have an active IIS Dynamic Compression Module configured at the server level "UseResponseCompression": false, - //Indicates whether to ignore DbVersionCheckMiddleware - "IgnoreDbVersionCheckMiddleware": false, //Indicates whether to ignore UsePoweredByMiddleware "IgnoreUsePoweredByMiddleware": false }, diff --git a/src/Web/Grand.Web/Grand.Web.csproj b/src/Web/Grand.Web/Grand.Web.csproj index e14340768..2dc8e420b 100644 --- a/src/Web/Grand.Web/Grand.Web.csproj +++ b/src/Web/Grand.Web/Grand.Web.csproj @@ -16,6 +16,7 @@ Linux + diff --git a/src/Web/Grand.Web/Program.cs b/src/Web/Grand.Web/Program.cs index d0bcaada7..fcce538dd 100644 --- a/src/Web/Grand.Web/Program.cs +++ b/src/Web/Grand.Web/Program.cs @@ -1,4 +1,4 @@ -using Grand.Web.Common.Extensions; +using Grand.Web.Common.Extensions; using Grand.Web.Common.Startup; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Hosting; @@ -6,6 +6,8 @@ var builder = WebApplication.CreateBuilder(args); +builder.AddServiceDefaults(); + builder.Host.UseDefaultServiceProvider((_, options) => { options.ValidateScopes = false;