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 0f7237ed31..f0c4c628b8 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,4 +1,6 @@ using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.DataAnnotations; @@ -104,7 +106,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ViewFeatures () => extensionPropertyInfo.DisplayName.Localize(_stringLocalizerFactory); } - foreach (var validationAttribute in extensionPropertyInfo.ValidationAttributes) + foreach (var validationAttribute in extensionPropertyInfo.GetValidationAttributes()) { var validationContext = new ClientModelValidationContext( viewContext, @@ -123,7 +125,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ViewFeatures _validationStringLocalizer ); - validationAttributeAdapter.AddValidation(validationContext); + validationAttributeAdapter?.AddValidation(validationContext); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs new file mode 100644 index 0000000000..e22f83d8ce --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs @@ -0,0 +1,91 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; + +namespace Volo.Abp.ObjectExtending +{ + public static class ObjectExtensionPropertyInfoAspNetCoreMvcExtensions + { + public static string GetInputType(this ObjectExtensionPropertyInfo propertyInfo) + { + foreach (var attribute in propertyInfo.Attributes) + { + var inputTypeByAttribute = GetInputTypeFromAttributeOrNull(attribute); + if (inputTypeByAttribute != null) + { + return inputTypeByAttribute; + } + } + + return GetInputTypeFromTypeOrNull(propertyInfo.Type) + ?? "text"; //default + } + + private static string GetInputTypeFromAttributeOrNull(Attribute attribute) + { + if (attribute is EmailAddressAttribute) + { + return "email"; + } + + if (attribute is UrlAttribute) + { + return "url"; + } + + if (attribute is HiddenInputAttribute) + { + return "hidden"; + } + + if (attribute is PhoneAttribute) + { + return "tel"; + } + + if (attribute is DataTypeAttribute dataTypeAttribute) + { + switch (dataTypeAttribute.DataType) + { + case DataType.Password: + return "password"; + case DataType.Date: + return "date"; + case DataType.Time: + return "time"; + //TODO: Others..? + } + } + + return null; + } + + private static string GetInputTypeFromTypeOrNull(Type type) + { + if (type == typeof(bool)) + { + return "checkbox"; + } + + if (type == typeof(DateTime)) + { + return "datetime-local"; + } + + if (type == typeof(int) || + type == typeof(long) || + type == typeof(byte) || + type == typeof(sbyte) || + type == typeof(short) || + type == typeof(ushort) || + type == typeof(uint) || + type == typeof(long) || + type == typeof(ulong)) + { + return "number"; + } + + return null; + } + } +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs index 07d6556d10..5832b98cd3 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs @@ -123,7 +123,9 @@ namespace Volo.Abp.ObjectExtending ValidationContext objectValidationContext, ObjectExtensionPropertyInfo property) { - if (!property.ValidationAttributes.Any()) + var validationAttributes = property.GetValidationAttributes(); + + if (!validationAttributes.Any()) { return; } @@ -134,7 +136,7 @@ namespace Volo.Abp.ObjectExtending MemberName = property.Name }; - foreach (var attribute in property.ValidationAttributes) + foreach (var attribute in validationAttributes) { var result = attribute.GetValidationResult( extensibleObject.GetProperty(property.Name), 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 8e8c0ecc03..c0792fbe51 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs @@ -18,8 +18,12 @@ namespace Volo.Abp.ObjectExtending public Type Type { get; } [NotNull] + [Obsolete("Add validation attributes to the Attributes list instead! ValidationAttributes property will be removed in future versions.")] public List ValidationAttributes { get; } + [NotNull] + public List Attributes { get; } + [NotNull] public List> Validators { get; } @@ -65,6 +69,7 @@ namespace Volo.Abp.ObjectExtending Configuration = new Dictionary(); ValidationAttributes = new List(); + Attributes = new List(); Validators = new List>(); } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoExtensions.cs new file mode 100644 index 0000000000..4eac846314 --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoExtensions.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; +using System.Linq; + +namespace Volo.Abp.ObjectExtending +{ + public static class ObjectExtensionPropertyInfoExtensions + { + public static ValidationAttribute[] GetValidationAttributes(this ObjectExtensionPropertyInfo propertyInfo) + { + return propertyInfo + .Attributes + .OfType() + .Union(propertyInfo.ValidationAttributes) + .ToArray(); + } + } +} diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObjectValidator_Tests.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObjectValidator_Tests.cs index 83ecc3100f..d08e3766df 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObjectValidator_Tests.cs +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObjectValidator_Tests.cs @@ -19,19 +19,19 @@ namespace Volo.Abp.ObjectExtending { options.AddOrUpdateProperty("Name", propertyInfo => { - propertyInfo.ValidationAttributes.Add(new RequiredAttribute()); - propertyInfo.ValidationAttributes.Add(new StringLengthAttribute(64) { MinimumLength = 2 }); + propertyInfo.Attributes.Add(new RequiredAttribute()); + propertyInfo.Attributes.Add(new StringLengthAttribute(64) { MinimumLength = 2 }); }); options.AddOrUpdateProperty("Address", propertyInfo => { - propertyInfo.ValidationAttributes.Add(new StringLengthAttribute(255)); + propertyInfo.Attributes.Add(new StringLengthAttribute(255)); }); options.AddOrUpdateProperty("Age", propertyInfo => { - propertyInfo.ValidationAttributes.Add(new RequiredAttribute()); - propertyInfo.ValidationAttributes.Add(new RangeAttribute(18, 99)); + propertyInfo.Attributes.Add(new RequiredAttribute()); + propertyInfo.Attributes.Add(new RangeAttribute(18, 99)); }); options.AddOrUpdateProperty("IsMarried", propertyInfo =>