diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs new file mode 100644 index 0000000000..b77354aab2 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs @@ -0,0 +1,63 @@ +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.ModelBinding.Metadata +{ + [Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] + [ExposeServices(typeof(IModelMetadataProvider))] + public class AbpModelMetadataProvider : DefaultModelMetadataProvider + { + private static readonly PropertyInfo ValidationAttributeErrorMessageStringProperty; + + static AbpModelMetadataProvider() + { + ValidationAttributeErrorMessageStringProperty = typeof(ValidationAttribute) + .GetProperty("ErrorMessageString", BindingFlags.Instance | BindingFlags.NonPublic); + } + + public AbpModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider) + : base(detailsProvider) + { + } + + public AbpModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider, IOptions optionsAccessor) + : base(detailsProvider, optionsAccessor) + { + } + + protected override DefaultMetadataDetails[] CreatePropertyDetails(ModelMetadataIdentity key) + { + var details = base.CreatePropertyDetails(key); + + foreach (var detail in details) + { + NormalizeMetadataDetail(detail); + } + + return details; + } + + private void NormalizeMetadataDetail(DefaultMetadataDetails detail) + { + foreach (var validationAttribute in detail.ModelAttributes.Attributes.OfType()) + { + NormalizeValidationAttrbute(validationAttribute); + } + } + + protected virtual void NormalizeValidationAttrbute(ValidationAttribute validationAttribute) + { + if (validationAttribute.ErrorMessage == null) + { + validationAttribute.ErrorMessage = ValidationAttributeErrorMessageStringProperty.GetValue(validationAttribute) as string; + } + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs index 339bac3dea..70fcd1f365 100644 --- a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs +++ b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs @@ -47,13 +47,13 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users public class UserInfoViewModel { - [Required(ErrorMessage = "The {0} field is required.")] + [Required] [MaxLength(IdentityUserConsts.MaxUserNameLength)] [Display(Name = "UserName")] public string UserName { get; set; } [Required] - [MaxLength(IdentityUserConsts.MaxPasswordLength, ErrorMessage = "The field {0} must be a string or array type with a maximum length of '{1}'.")] + [MaxLength(IdentityUserConsts.MaxPasswordLength)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; }