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 d49e2c15e6..00ba8423b3 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 @@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Localization; using Volo.Abp.ApiVersioning; using Volo.Abp.AspNetCore.Mvc.ApiExploring; using Volo.Abp.AspNetCore.Mvc.Conventions; @@ -114,8 +115,17 @@ namespace Volo.Abp.AspNetCore.Mvc { options.DataAnnotationLocalizerProvider = (type, factory) => { - var resourceType = abpMvcDataAnnotationsLocalizationOptions.AssemblyResources.GetOrDefault(type.Assembly); - return factory.Create(resourceType ?? type); + var resourceType = abpMvcDataAnnotationsLocalizationOptions + .AssemblyResources + .GetOrDefault(type.Assembly); + + if (resourceType != null) + { + return factory.Create(resourceType); + } + + return factory.CreateDefaultOrNull() ?? + 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. diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index 52af9090fa..187823b663 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -76,7 +76,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations }; } - protected virtual CurrentTenantDto GetCurrentTenant() + protected virtual CurrentTenantDto GetCurrentTenant() { return new CurrentTenantDto() { @@ -157,9 +157,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations } localizationConfig.CurrentCulture = GetCurrentCultureInfo(); - localizationConfig.DefaultResourceName = LocalizationResourceNameAttribute.GetName( - _localizationOptions.DefaultResourceType - ); + + if (_localizationOptions.DefaultResourceType != null) + { + localizationConfig.DefaultResourceName = LocalizationResourceNameAttribute.GetName( + _localizationOptions.DefaultResourceType + ); + } Logger.LogDebug("Executed AbpApplicationConfigurationAppService.GetLocalizationConfigAsync()"); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ViewFeatures/AbpValidationHtmlAttributeProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ViewFeatures/AbpValidationHtmlAttributeProvider.cs index 563ebe9d4a..84a3d05e25 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ViewFeatures/AbpValidationHtmlAttributeProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ViewFeatures/AbpValidationHtmlAttributeProvider.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.DataAnnotations; @@ -14,6 +13,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.ModelBinding; using Volo.Abp.AspNetCore.Mvc.Validation; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; using Volo.Abp.ObjectExtending; using Volo.Abp.Validation.Localization; @@ -103,7 +103,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ViewFeatures if (modelExplorer.Metadata is DefaultModelMetadata metadata) { metadata.DisplayMetadata.DisplayName = - () => extensionPropertyInfo.GetDisplayName(_stringLocalizerFactory); + () => extensionPropertyInfo.GetLocalizedDisplayName(_stringLocalizerFactory); } foreach (var validationAttribute in extensionPropertyInfo.GetValidationAttributes()) diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs new file mode 100644 index 0000000000..4d42b73537 --- /dev/null +++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs @@ -0,0 +1,36 @@ +using System; +using JetBrains.Annotations; +using Microsoft.Extensions.Localization; + +namespace Volo.Abp.Localization +{ + public static class HasNameWithLocalizableDisplayNameExtensions + { + [NotNull] + public static string GetLocalizedDisplayName( + [NotNull] this IHasNameWithLocalizableDisplayName source, + [NotNull] IStringLocalizerFactory stringLocalizerFactory, + [CanBeNull] string localizationNamePrefix = "DisplayName:") + { + if (source.DisplayName != null) + { + return source.DisplayName.Localize(stringLocalizerFactory); + } + + var defaultStringLocalizer = stringLocalizerFactory.CreateDefaultOrNull(); + if (defaultStringLocalizer == null) + { + return source.Name; + } + + var localizedString = defaultStringLocalizer[$"{localizationNamePrefix}{source.Name}"]; + if (!localizedString.ResourceNotFound || + localizationNamePrefix.IsNullOrEmpty()) + { + return localizedString; + } + + return defaultStringLocalizer[source.Name]; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs new file mode 100644 index 0000000000..8be0d7d2de --- /dev/null +++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs @@ -0,0 +1,13 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Localization +{ + public interface IHasNameWithLocalizableDisplayName + { + [NotNull] + public string Name { get; } + + [CanBeNull] + public ILocalizableString DisplayName { get; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs index 59f42b1494..5d55325477 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs @@ -7,7 +7,7 @@ using Volo.Abp.Localization; namespace Volo.Abp.ObjectExtending { - public class ObjectExtensionPropertyInfo + public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName { [NotNull] public ObjectExtensionInfo ObjectExtension { get; } @@ -62,35 +62,5 @@ namespace Volo.Abp.ObjectExtending Attributes = new List(); Validators = new List>(); } - - [NotNull] - public string GetDisplayName( - [NotNull] IStringLocalizerFactory stringLocalizerFactory) - { - if (DisplayName != null) - { - return DisplayName.Localize(stringLocalizerFactory); - } - - var defaultStringLocalizer = stringLocalizerFactory.CreateDefaultOrNull(); - if (defaultStringLocalizer == null) - { - return Name; - } - - var localizedString = defaultStringLocalizer[$"DisplayName:{Name}"]; - if (!localizedString.ResourceNotFound) - { - return localizedString; - } - - localizedString = defaultStringLocalizer[Name]; - if (!localizedString.ResourceNotFound) - { - return localizedString; - } - - return Name; - } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index db2ccf6f63..948c1712db 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -5,7 +5,7 @@ using Volo.Abp.Localization; namespace Volo.Abp.TextTemplating { - public class TemplateDefinition + public class TemplateDefinition : IHasNameWithLocalizableDisplayName { public const int MaxNameLength = 128; diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs index f51e8447b0..86eb684f52 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; using Scriban; using Scriban.Runtime; using Volo.Abp.DependencyInjection; @@ -136,9 +137,9 @@ namespace Volo.Abp.TextTemplating scriptObject["model"] = model; } - if (templateDefinition.LocalizationResource != null) + var localizer = GetLocalizerOrNull(templateDefinition); + if (localizer != null) { - var localizer = _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); scriptObject.Import( "L", new Func( @@ -151,5 +152,15 @@ namespace Volo.Abp.TextTemplating return context; } + + private IStringLocalizer GetLocalizerOrNull(TemplateDefinition templateDefinition) + { + if (templateDefinition.LocalizationResource != null) + { + return _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); + } + + return _stringLocalizerFactory.CreateDefaultOrNull(); + } } } \ No newline at end of file