From 1913ced92eb51691a079a0144e42ce3a4e8a9fe5 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 1 Aug 2018 17:41:08 +0300 Subject: [PATCH 1/2] Automatically localize display name for model properties (without Display attribute). --- ...AutoLocalizationMetadataDetailsProvider.cs | 50 +++++++++++++++++++ .../AspNetCore/Mvc/AbpMvcOptionsExtensions.cs | 8 +++ .../App/LocalizationTestController.cs | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs new file mode 100644 index 0000000000..e167cc9ec2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs @@ -0,0 +1,50 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using Microsoft.AspNetCore.Mvc.DataAnnotations; +using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Mvc +{ + public class AbpDataAnnotationAutoLocalizationMetadataDetailsProvider : IDisplayMetadataProvider + { + private readonly Lazy _stringLocalizerFactory; + private readonly Lazy> _localizationOptions; + + public AbpDataAnnotationAutoLocalizationMetadataDetailsProvider(IServiceCollection services) + { + _stringLocalizerFactory = services.GetRequiredServiceLazy(); + _localizationOptions = services.GetRequiredServiceLazy>(); + } + + public void CreateDisplayMetadata(DisplayMetadataProviderContext context) + { + var displayMetadata = context.DisplayMetadata; + + if (displayMetadata.DisplayName != null) + { + return; + } + + var attributes = context.Attributes; + var displayAttribute = attributes.OfType().FirstOrDefault(); + var displayNameAttribute = attributes.OfType().FirstOrDefault(); + + if (displayAttribute != null || displayNameAttribute != null) + { + return; + } + + var containerType = context.Key.ContainerType ?? context.Key.ModelType; + var localizer = _localizationOptions.Value.Value.DataAnnotationLocalizerProvider(containerType, _stringLocalizerFactory.Value); + if (context.Key.Name == "BirthDate") + { + displayMetadata.DisplayName = () => localizer[context.Key.Name]; + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs index dd509b1746..4de46b2f0b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs @@ -15,6 +15,7 @@ namespace Volo.Abp.AspNetCore.Mvc AddConventions(options, services); AddFilters(options); AddModelBinders(options); + AddMetadataProviders(options, services); } private static void AddConventions(MvcOptions options, IServiceCollection services) @@ -34,5 +35,12 @@ namespace Volo.Abp.AspNetCore.Mvc { //options.ModelBinderProviders.Add(new AbpDateTimeModelBinderProvider()); } + + private static void AddMetadataProviders(MvcOptions options, IServiceCollection services) + { + options.ModelMetadataDetailsProviders.Add( + new AbpDataAnnotationAutoLocalizationMetadataDetailsProvider(services) + ); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs index 184bfe1c99..1a9b6e7de8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/LocalizationTestController.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.App public class PersonModel { - [Display(Name = nameof(BirthDate))] + //[Display(Name = nameof(BirthDate))] public string BirthDate { get; set; } public PersonModel() From fc40d2f79bf881a3334c454cceb81ed1bf54e575 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 2 Aug 2018 16:43:28 +0300 Subject: [PATCH 2/2] Refactored AbpDataAnnotationAutoLocalizationMetadataDetailsProvider --- ...AutoLocalizationMetadataDetailsProvider.cs | 27 ++++++++++++++----- ...bpMvcDataAnnotationsLocalizationOptions.cs | 4 +-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs index e167cc9ec2..fae03d74b8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpDataAnnotationAutoLocalizationMetadataDetailsProvider.cs @@ -12,6 +12,8 @@ namespace Volo.Abp.AspNetCore.Mvc { public class AbpDataAnnotationAutoLocalizationMetadataDetailsProvider : IDisplayMetadataProvider { + private const string PropertyLocalizationKeyPrefix = "Property:"; + private readonly Lazy _stringLocalizerFactory; private readonly Lazy> _localizationOptions; @@ -24,27 +26,38 @@ namespace Volo.Abp.AspNetCore.Mvc public void CreateDisplayMetadata(DisplayMetadataProviderContext context) { var displayMetadata = context.DisplayMetadata; - if (displayMetadata.DisplayName != null) { return; } var attributes = context.Attributes; - var displayAttribute = attributes.OfType().FirstOrDefault(); - var displayNameAttribute = attributes.OfType().FirstOrDefault(); - if (displayAttribute != null || displayNameAttribute != null) + if (attributes.OfType().Any() || + attributes.OfType().Any()) + { + return; + } + + if (_localizationOptions.Value.Value.DataAnnotationLocalizerProvider == null) { return; } var containerType = context.Key.ContainerType ?? context.Key.ModelType; var localizer = _localizationOptions.Value.Value.DataAnnotationLocalizerProvider(containerType, _stringLocalizerFactory.Value); - if (context.Key.Name == "BirthDate") + + displayMetadata.DisplayName = () => { - displayMetadata.DisplayName = () => localizer[context.Key.Name]; - } + var localizedString = localizer[PropertyLocalizationKeyPrefix + context.Key.Name]; + + if (localizedString.ResourceNotFound) + { + localizedString = localizer[context.Key.Name]; + } + + return localizedString; + }; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcDataAnnotationsLocalizationOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcDataAnnotationsLocalizationOptions.cs index bca738b101..70c15cfd55 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcDataAnnotationsLocalizationOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpMvcDataAnnotationsLocalizationOptions.cs @@ -15,12 +15,12 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization } public void AddAssemblyResource( - [NotNull] Type resourceType, + [NotNull] Type resourceType, params Assembly[] assemblies) { if (assemblies.IsNullOrEmpty()) { - assemblies = new Assembly[] {resourceType.Assembly}; + assemblies = new[] { resourceType.Assembly }; } foreach (var assembly in assemblies)