diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index b295f19cc6..c5b72a6c1d 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -21,7 +21,7 @@ This tutorial explains how to start ABP from scratch with minimal dependencies. Volo.Abp.AspNetCore.Mvc is the AspNet Core MVC integration package for ABP. So, install it on your project: ```` -Install-Package Volo.Abp.AspNetCore.Mvc -Version 5.0.0-rc.1 +Install-Package Volo.Abp.AspNetCore.Mvc ```` ## Create the First ABP Module @@ -105,7 +105,7 @@ Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty ea 1. Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) package ```` -Install-Package Volo.Abp.Autofac -Version 5.0.0-rc.1 +Install-Package Volo.Abp.Autofac ```` 2. Add the ``AbpAutofacModule`` Dependency diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 4d7a912426..3bc99436ca 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -54,7 +54,7 @@ public class AbpInputTagHelperService : AbpTagHelperService output.TagMode = TagMode.StartTagAndEndTag; output.TagName = "div"; LeaveOnlyGroupAttributes(context, output); - output.Attributes.AddClass("mb-3"); + output.Attributes.AddClass(isCheckBox ? "mb-2" : "mb-3"); if (isCheckBox) { output.Attributes.AddClass("form-check"); @@ -104,9 +104,9 @@ public class AbpInputTagHelperService : AbpTagHelperService protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml, bool isCheckbox) { - return "
" + - Environment.NewLine + innerHtml + Environment.NewLine + - "
"; + return "
" + + Environment.NewLine + innerHtml + Environment.NewLine + + "
"; } protected virtual TagHelper GetInputTagHelper(TagHelperContext context, TagHelperOutput output) @@ -197,7 +197,7 @@ public class AbpInputTagHelperService : AbpTagHelperService protected virtual void AddDisabledAttribute(TagHelperOutput inputTagHelperOutput) { if (inputTagHelperOutput.Attributes.ContainsName("disabled") == false && - (TagHelper.IsDisabled || TagHelper.AspFor.ModelExplorer.GetAttribute() != null)) + (TagHelper.IsDisabled || TagHelper.AspFor.ModelExplorer.GetAttribute() != null)) { inputTagHelperOutput.Attributes.Add("disabled", ""); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js index f89f6ffed7..6f2a5cd727 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js @@ -101,6 +101,9 @@ var abp = abp || {}; var l = abp.localization.getResource('AbpUi'); abp.libs.sweetAlert.config.confirm.title = l('AreYouSure'); + abp.libs.sweetAlert.config.confirm.confirmButtonText = l('Yes'); + abp.libs.sweetAlert.config.confirm.denyButtonText = l('No'); + abp.libs.sweetAlert.config.confirm.cancelButtonText = l('Cancel'); abp.libs.sweetAlert.config.confirm.showCancelButton = true; abp.libs.sweetAlert.config.confirm.reverseButtons = true; }); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpMvcBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpMvcBuilderExtensions.cs index 5d66ec7821..57aa64be6a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpMvcBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpMvcBuilderExtensions.cs @@ -1,7 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation; +using Volo.Abp.AspNetCore.VirtualFileSystem; +using Volo.Abp.DependencyInjection; namespace Microsoft.Extensions.DependencyInjection; @@ -27,4 +31,17 @@ public static class AbpMvcBuilderExtensions applicationParts.Add(new AssemblyPart(assembly)); } + + public static void AddAbpRazorRuntimeCompilation(this IMvcCoreBuilder mvcCoreBuilder) + { + mvcCoreBuilder.AddRazorRuntimeCompilation(); + mvcCoreBuilder.Services.Configure(options => + { + options.FileProviders.Add( + new RazorViewEngineVirtualFileProvider( + mvcCoreBuilder.Services.GetSingletonInstance>() + ) + ); + }); + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index c957a3c645..c205e15321 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -77,12 +77,12 @@ public class AbpAspNetCoreMvcModule : AbpModule { var statusCodes = new List { - (int) HttpStatusCode.Forbidden, - (int) HttpStatusCode.Unauthorized, - (int) HttpStatusCode.BadRequest, - (int) HttpStatusCode.NotFound, - (int) HttpStatusCode.NotImplemented, - (int) HttpStatusCode.InternalServerError + (int) HttpStatusCode.Forbidden, + (int) HttpStatusCode.Unauthorized, + (int) HttpStatusCode.BadRequest, + (int) HttpStatusCode.NotFound, + (int) HttpStatusCode.NotImplemented, + (int) HttpStatusCode.InternalServerError }; options.SupportedResponseTypes.AddIfNotContains(statusCodes.Select(statusCode => new ApiResponseType @@ -119,7 +119,6 @@ public class AbpAspNetCoreMvcModule : AbpModule ); var mvcBuilder = context.Services.AddMvc() - .AddRazorRuntimeCompilation() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => @@ -134,21 +133,18 @@ public class AbpAspNetCoreMvcModule : AbpModule } return factory.CreateDefaultOrNull() ?? - factory.Create(type); + factory.Create(type); }; }) .AddViewLocalization(); //TODO: How to configure from the application? Also, consider to move to a UI module since APIs does not care about it. - mvcCoreBuilder.AddAbpHybridJson(); - - Configure(options => + if (context.Services.GetHostingEnvironment().IsDevelopment() && + context.Services.ExecutePreConfiguredActions().EnableRazorRuntimeCompilationOnDevelopment) { - options.FileProviders.Add( - new RazorViewEngineVirtualFileProvider( - context.Services.GetSingletonInstance>() - ) - ); - }); + mvcCoreBuilder.AddAbpRazorRuntimeCompilation(); + } + + mvcCoreBuilder.AddAbpHybridJson(); context.Services.ExecutePreConfiguredActions(mvcBuilder); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs index e21e33de04..e615be5ecb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs @@ -14,10 +14,13 @@ public class AbpAspNetCoreMvcOptions public bool AutoModelValidation { get; set; } + public bool EnableRazorRuntimeCompilationOnDevelopment { get; set; } + public AbpAspNetCoreMvcOptions() { ConventionalControllers = new AbpConventionalControllerOptions(); IgnoredControllersOnModelExclusion = new HashSet(); AutoModelValidation = true; + EnableRazorRuntimeCompilationOnDevelopment = true; } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj index fe87db9cd1..8832400d64 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj +++ b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs index 51b394fd3f..de57a20d83 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Cli.Bundling; public abstract class BundlerBase : IBundler, ITransientDependency { - private static string[] _minFileSuffixes = { "min", "prod" }; + private static string[] _minFileSuffixes = {"min", "prod"}; protected IMinifier Minifier { get; } public ILogger Logger { get; set; } @@ -38,7 +38,7 @@ public abstract class BundlerBase : IBundler, ITransientDependency var bundledContent = BundleFiles(options, bundleFileDefinitions); File.WriteAllText(bundleFilePath, bundledContent); - return GenerateDefinition(bundleFilePath, fileDefinitionsExcludingFromBundle); + return GenerateDefinition(bundleFilePath,fileDefinitionsExcludingFromBundle); } private bool IsMinFile(string fileName, string content) @@ -85,7 +85,7 @@ public abstract class BundlerBase : IBundler, ITransientDependency { var pathFragments = definition.Source.Split('/').ToList(); var basePath = $"{pathFragments[0]}/{pathFragments[1]}"; - var path = contentRoots.FirstOrDefault(x => x.IndexOf($"\\{pathFragments[1]}\\", StringComparison.OrdinalIgnoreCase) > 0); + var path = contentRoots.FirstOrDefault(x => x.IndexOf(Path.DirectorySeparatorChar + pathFragments[1] + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) > 0); if (path == null) { throw new AbpException("Not found: " + definition.Source); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index 3a923ba799..4e1b5e1334 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -40,36 +40,6 @@ PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 28254a9eb5..2a48bbc8e7 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Security.Claims; using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Authorization; @@ -69,12 +70,12 @@ public class AbpAspNetCoreMvcTestModule : AbpModule options.AddPolicy("TestPermission1_And_TestPermission2", policy => { - policy.Requirements.Add(new PermissionsRequirement(new[] { "TestPermission1", "TestPermission2" }, requiresAll: true)); + policy.Requirements.Add(new PermissionsRequirement(new []{"TestPermission1", "TestPermission2"}, requiresAll: true)); }); options.AddPolicy("TestPermission1_Or_TestPermission2", policy => { - policy.Requirements.Add(new PermissionsRequirement(new[] { "TestPermission1", "TestPermission2" }, requiresAll: false)); + policy.Requirements.Add(new PermissionsRequirement(new []{"TestPermission1", "TestPermission2"}, requiresAll: false)); }); }); @@ -115,6 +116,11 @@ public class AbpAspNetCoreMvcTestModule : AbpModule options.RootDirectory = "/Volo/Abp/AspNetCore/Mvc"; }); + Configure(options => + { + options.ViewLocationFormats.Add("/Volo/Abp/AspNetCore/App/Views/{1}/{0}.cshtml"); + }); + Configure(options => { options.Maps.Add("SerialNumber", () => ClaimTypes.SerialNumber); diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs index d76bdd0a77..5a5567c81e 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs @@ -137,7 +137,7 @@ namespace Volo.Docs.Areas.Documents.TagHelpers } else if (node.LastSignificantUpdateTime != null && node.LastSignificantUpdateTime + TimeSpan.FromDays(14) > DateTime.Now) { - var updBadge = sb.Append("").Append(_localizer["Upd"]).Append("").ToString(); + var updBadge = sb.Append("").Append(_localizer["Upd"]).Append("").ToString(); badgeStringBuilder.Append(updBadge); } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupService.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupService.cs index c83ed22a52..98384a448c 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupService.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupService.cs @@ -1,9 +1,9 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.IdentityServer.Devices; using Volo.Abp.IdentityServer.Grants; -using Volo.Abp.Timing; using Volo.Abp.Uow; namespace Volo.Abp.IdentityServer.Tokens; @@ -12,43 +12,32 @@ public class TokenCleanupService : ITransientDependency { protected IPersistentGrantRepository PersistentGrantRepository { get; } protected IDeviceFlowCodesRepository DeviceFlowCodesRepository { get; } - protected IClock Clock { get; } protected TokenCleanupOptions Options { get; } public TokenCleanupService( IPersistentGrantRepository persistentGrantRepository, IDeviceFlowCodesRepository deviceFlowCodesRepository, - IClock clock, IOptions options) { PersistentGrantRepository = persistentGrantRepository; DeviceFlowCodesRepository = deviceFlowCodesRepository; - Clock = clock; Options = options.Value; } public virtual async Task CleanAsync() { - await RemoveGrantsAsync() - ; - + await RemoveGrantsAsync(); await RemoveDeviceCodesAsync(); } [UnitOfWork] protected virtual async Task RemoveGrantsAsync() { - for (int i = 0; i < Options.CleanupLoopCount; i++) + for (var i = 0; i < Options.CleanupLoopCount; i++) { - var persistentGrants = await PersistentGrantRepository - .GetListByExpirationAsync(Clock.Now, Options.CleanupBatchSize); + var persistentGrants = await PersistentGrantRepository.GetListByExpirationAsync(DateTime.UtcNow, Options.CleanupBatchSize); - //TODO: Can be optimized if the repository implements the batch deletion - foreach (var persistentGrant in persistentGrants) - { - await PersistentGrantRepository - .DeleteAsync(persistentGrant); - } + await PersistentGrantRepository.DeleteManyAsync(persistentGrants); //No need to continue to query if it gets more than max items. if (persistentGrants.Count < Options.CleanupBatchSize) @@ -60,17 +49,11 @@ public class TokenCleanupService : ITransientDependency protected virtual async Task RemoveDeviceCodesAsync() { - for (int i = 0; i < Options.CleanupLoopCount; i++) + for (var i = 0; i < Options.CleanupLoopCount; i++) { - var deviceFlowCodeses = await DeviceFlowCodesRepository - .GetListByExpirationAsync(Clock.Now, Options.CleanupBatchSize); + var deviceFlowCodeses = await DeviceFlowCodesRepository.GetListByExpirationAsync(DateTime.UtcNow, Options.CleanupBatchSize); - //TODO: Can be optimized if the repository implements the batch deletion - foreach (var deviceFlowCodes in deviceFlowCodeses) - { - await DeviceFlowCodesRepository - .DeleteAsync(deviceFlowCodes); - } + await DeviceFlowCodesRepository.DeleteManyAsync(deviceFlowCodeses); //No need to continue to query if it gets more than max items. if (deviceFlowCodeses.Count < Options.CleanupBatchSize) diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 93b540f40a..e173a913c2 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -266,7 +266,7 @@ $projects = ( "modules/docs/src/Volo.Docs.HttpApi.Client", "modules/docs/src/Volo.Docs.HttpApi", "modules/docs/src/Volo.Docs.MongoDB", - "modules/docs/src/Volo.Docs.Web",, + "modules/docs/src/Volo.Docs.Web", "studio/source-codes/Volo.Docs.SourceCode", # modules/feature-management diff --git a/nupkg/push_packages.ps1 b/nupkg/push_packages.ps1 index cb6456e1d3..6fa91a5599 100644 --- a/nupkg/push_packages.ps1 +++ b/nupkg/push_packages.ps1 @@ -9,6 +9,7 @@ $version = $commonPropsXml.Project.PropertyGroup.Version # Publish all packages $i = 0 $errorCount = 0 +$totalProjectsCount = $projects.length $nugetUrl = "https://api.nuget.org/v3/index.json" Set-Location $packFolder @@ -19,12 +20,12 @@ foreach($project in $projects) { $nugetPackageName = $projectName + "." + $version + ".nupkg" $nugetPackageExists = Test-Path $nugetPackageName -PathType leaf - Write-Host ("-----===[ $i / " + $projects.length + " - " + $nugetPackageName + " ]===-----") + Write-Info "[$i / $totalProjectsCount] - Pushing: $nugetPackageName" if ($nugetPackageExists) { dotnet nuget push $nugetPackageName --skip-duplicate -s $nugetUrl --api-key "$apiKey" - Write-Host ("Deleting package from local: " + $nugetPackageName) + #Write-Host ("Deleting package from local: " + $nugetPackageName) #Remove-Item $nugetPackageName -Force } else