fix(module: form): validation attributes transfer (#4084)
* fix(module: form): validation attribute transfer * add missing required parameter to rules * fix enum validate messages * fix test * fix field type * fix test * fix test * fix test
This commit is contained in:
Родитель
5d153a6e05
Коммит
04b4b47b94
|
@ -38,6 +38,8 @@ namespace AntDesign
|
|||
|
||||
internal PropertyReflector? PopertyReflector => _propertyReflector;
|
||||
|
||||
internal Type ValueUnderlyingType => _nullableUnderlyingType ?? typeof(TValue);
|
||||
|
||||
[CascadingParameter(Name = "FormItem")]
|
||||
protected IFormItem FormItem { get; set; }
|
||||
|
||||
|
@ -370,8 +372,6 @@ namespace AntDesign
|
|||
}
|
||||
}
|
||||
|
||||
FieldIdentifier IControlValueAccessor.FieldIdentifier => FieldIdentifier;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
|
@ -403,10 +403,10 @@ namespace AntDesign
|
|||
}
|
||||
|
||||
EditContext = Form?.EditContext;
|
||||
|
||||
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
|
||||
}
|
||||
|
||||
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
|
||||
|
||||
EditContext.OnValidationStateChanged += _validationStateChangedHandler;
|
||||
|
||||
if (ValueExpression != null)
|
||||
|
@ -484,10 +484,5 @@ namespace AntDesign
|
|||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void IControlValueAccessor.OnValidated(string[] validationMessages)
|
||||
{
|
||||
OnValidated(validationMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
String = _typeTemplate,
|
||||
Array = _typeTemplate,
|
||||
Object = _typeTemplate,
|
||||
Enum = _typeTemplate,
|
||||
Number = _typeTemplate,
|
||||
Date = _typeTemplate,
|
||||
Boolean = _typeTemplate,
|
||||
|
@ -32,7 +31,7 @@
|
|||
Url = _typeTemplate,
|
||||
};
|
||||
|
||||
public StringMessage String { get; set; } = new()
|
||||
public CompareMessage String { get; set; } = new()
|
||||
{
|
||||
Len = "'{0}' must be exactly {1} characters",
|
||||
Min = "'{0}' must be at least {1} characters",
|
||||
|
@ -40,7 +39,7 @@
|
|||
Range = "'{0}' must be between {1} and {2} characters",
|
||||
};
|
||||
|
||||
public NumberMessage Number { get; set; } = new()
|
||||
public CompareMessage Number { get; set; } = new()
|
||||
{
|
||||
Len = "'{0}' must equal {1}",
|
||||
Min = "'{0}' cannot be less than {1}",
|
||||
|
@ -48,7 +47,7 @@
|
|||
Range = "'{0}' must be between {1} and {2}",
|
||||
};
|
||||
|
||||
public ArrayMessage Array { get; set; } = new()
|
||||
public CompareMessage Array { get; set; } = new()
|
||||
{
|
||||
Len = "'{0}' must be exactly {1} in length",
|
||||
Min = "'{0}' cannot be less than {1} in length",
|
||||
|
@ -73,7 +72,6 @@
|
|||
FormFieldType.Float => Types.Float,
|
||||
FormFieldType.Array => Types.Array,
|
||||
FormFieldType.Object => Types.Object,
|
||||
FormFieldType.Enum => Types.Enum,
|
||||
FormFieldType.Date => Types.Date,
|
||||
FormFieldType.Url => Types.Url,
|
||||
FormFieldType.Email => Types.Email,
|
||||
|
@ -87,7 +85,6 @@
|
|||
public string String { get; set; }
|
||||
public string Array { get; set; }
|
||||
public string Object { get; set; }
|
||||
public string Enum { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string Date { get; set; }
|
||||
public string Boolean { get; set; }
|
||||
|
@ -98,7 +95,7 @@
|
|||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public class StringMessage
|
||||
public class CompareMessage
|
||||
{
|
||||
public string Len { get; set; }
|
||||
public string Min { get; set; }
|
||||
|
@ -106,24 +103,6 @@
|
|||
public string Range { get; set; }
|
||||
}
|
||||
|
||||
public class NumberMessage
|
||||
{
|
||||
public string Len { get; set; }
|
||||
public string Min { get; set; }
|
||||
public string Max { get; set; }
|
||||
public string Range { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ArrayMessage
|
||||
{
|
||||
public string Len { get; set; }
|
||||
public string Min { get; set; }
|
||||
public string Max { get; set; }
|
||||
public string Range { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class PatternMessage
|
||||
{
|
||||
public string Mismatch { get; set; }
|
||||
|
|
|
@ -7,8 +7,6 @@ namespace AntDesign.Forms
|
|||
{
|
||||
public interface IControlValueAccessor
|
||||
{
|
||||
internal FieldIdentifier FieldIdentifier { get; }
|
||||
void OnValidated(string[] validationMessages);
|
||||
internal void Reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace AntDesign
|
|||
_enumType = THelper.GetUnderlyingType<T>();
|
||||
_aggregateFunction = BuildAggregateFunction();
|
||||
_valueList = Enum.GetValues(_enumType).Cast<T>();
|
||||
_valueLabelList = _valueList.Select(value => (value, GetDisplayName(value)));
|
||||
_valueLabelList = _valueList.Select(value => (value, EnumHelper.GetDisplayName(_enumType, value)));
|
||||
_isFlags = _enumType.GetCustomAttribute<FlagsAttribute>() != null;
|
||||
_hasFlagFunction = BuildHasFlagFunction();
|
||||
}
|
||||
|
@ -68,11 +68,9 @@ namespace AntDesign
|
|||
return _valueLabelList;
|
||||
}
|
||||
|
||||
public static string GetDisplayName(T enumValue)
|
||||
public static string GetDisplayName<TEnum>(TEnum item)
|
||||
{
|
||||
var enumName = Enum.GetName(_enumType, enumValue);
|
||||
var fieldInfo = _enumType.GetField(enumName);
|
||||
return fieldInfo.GetCustomAttribute<DisplayAttribute>(true)?.GetName() ?? enumName;
|
||||
return EnumHelper.GetDisplayName(_enumType, item);
|
||||
}
|
||||
|
||||
private static Func<T, T, T> BuildAggregateFunction()
|
||||
|
@ -111,4 +109,14 @@ namespace AntDesign
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class EnumHelper
|
||||
{
|
||||
public static string GetDisplayName(Type enumType, object enumValue)
|
||||
{
|
||||
var enumName = Enum.GetName(enumType, enumValue);
|
||||
var fieldInfo = enumType.GetField(enumName);
|
||||
return fieldInfo.GetCustomAttribute<DisplayAttribute>(true)?.GetName() ?? enumName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ using System.Reflection;
|
|||
|
||||
namespace AntDesign
|
||||
{
|
||||
public static class THelper
|
||||
internal static class THelper
|
||||
{
|
||||
public static T ChangeType<T>(object value)
|
||||
{
|
||||
|
@ -98,9 +98,22 @@ namespace AntDesign
|
|||
or TypeCode.UInt32
|
||||
or TypeCode.UInt64;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsDateType(this Type type)
|
||||
{
|
||||
return type != null && (type == typeof(DateTime)
|
||||
|| type == typeof(DateTimeOffset)
|
||||
#if NET6_0_OR_GREATER
|
||||
|| type == typeof(TimeOnly)
|
||||
|| type == typeof(DateOnly)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
public static bool IsArrayOrList(this Type that) => that != null && (that.IsArray || typeof(IList).IsAssignableFrom(that));
|
||||
|
||||
public static bool IsEnumerable(this Type that) => that != null && (that.IsArray || typeof(IEnumerable).IsAssignableFrom(that));
|
||||
|
||||
public static bool IsUserDefinedClass(this Type thta) =>
|
||||
thta.IsClass && thta.Namespace != null && !thta.Namespace.StartsWith("System");
|
||||
}
|
||||
|
|
|
@ -393,7 +393,7 @@ namespace AntDesign
|
|||
|
||||
bool UseRulesValidator => UseLocaleValidateMessage || ValidateMode != FormValidateMode.Default;
|
||||
|
||||
public void BuildEditContext()
|
||||
private void BuildEditContext()
|
||||
{
|
||||
if (_editContext == null)
|
||||
return;
|
||||
|
|
|
@ -186,6 +186,11 @@ namespace AntDesign
|
|||
|
||||
private string DisplayName => Label ?? _propertyReflector?.DisplayName;
|
||||
|
||||
private string _name;
|
||||
private Action _nameChanged;
|
||||
|
||||
private Type _valueUnderlyingType;
|
||||
|
||||
private FieldIdentifier _fieldIdentifier;
|
||||
private Func<object, object> _fieldValueGetter;
|
||||
|
||||
|
@ -195,10 +200,8 @@ namespace AntDesign
|
|||
private FormValidateStatus? _originalValidateStatus;
|
||||
private Action _vaildateStatusChanged;
|
||||
|
||||
private Action _nameChanged;
|
||||
private Action<string[]> _onValidated;
|
||||
|
||||
private string _name;
|
||||
private IEnumerable<FormValidationRule> _rules;
|
||||
|
||||
RenderFragment IFormItem.FeedbackIcon => IsShowIcon ? builder =>
|
||||
|
@ -270,6 +273,11 @@ namespace AntDesign
|
|||
FormValidateMode.Rules => Rules ?? [],
|
||||
_ => [.. GetRulesFromAttributes(), .. Rules ?? []]
|
||||
};
|
||||
|
||||
if (Required && !_rules.Any(rule => rule.Required == true || rule.ValidationAttribute is RequiredAttribute))
|
||||
{
|
||||
_rules = [.. _rules, new FormValidationRule { Required = true }];
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
|
@ -404,6 +412,7 @@ namespace AntDesign
|
|||
_vaildateStatusChanged = control.UpdateStyles;
|
||||
_nameChanged = control.OnNameChanged;
|
||||
_onValidated = control.OnValidated;
|
||||
_valueUnderlyingType = control.ValueUnderlyingType;
|
||||
|
||||
if (control.FieldIdentifier.Model == null)
|
||||
{
|
||||
|
@ -459,6 +468,11 @@ namespace AntDesign
|
|||
return [];
|
||||
}
|
||||
|
||||
if (IsRequired)
|
||||
{
|
||||
_rules ??= [];
|
||||
}
|
||||
|
||||
if (_rules?.Any() != true)
|
||||
{
|
||||
return [];
|
||||
|
@ -480,6 +494,7 @@ namespace AntDesign
|
|||
Value = propertyValue,
|
||||
FieldName = _fieldIdentifier.FieldName,
|
||||
DisplayName = DisplayName,
|
||||
FieldType = _valueUnderlyingType,
|
||||
ValidateMessages = validateMessages,
|
||||
};
|
||||
|
||||
|
@ -524,8 +539,7 @@ namespace AntDesign
|
|||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
|
||||
yield return new FormValidationRule { ValidationAttribute = attribute };
|
||||
yield return new FormValidationRule { ValidationAttribute = attribute, Enum = _valueUnderlyingType.IsEnum ? _valueUnderlyingType : null };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Numerics;
|
||||
using System.Linq;
|
||||
|
||||
namespace AntDesign.Internal.Form.Validate
|
||||
{
|
||||
|
@ -43,25 +43,29 @@ namespace AntDesign.Internal.Form.Validate
|
|||
|
||||
var templates = validationContext.ValidateMessages;
|
||||
|
||||
var compareMessage = validationContext.FieldType switch
|
||||
{
|
||||
Type t when t == typeof(string) => templates.String,
|
||||
Type t when THelper.IsNumericType(t) => templates.Number,
|
||||
Type t when THelper.IsEnumerable(t) => templates.Array,
|
||||
_ => templates.String
|
||||
};
|
||||
|
||||
attribute.ErrorMessage = attribute switch
|
||||
{
|
||||
// if user has set the ErrorMessage, we will use it directly
|
||||
{ ErrorMessage.Length: > 0 } => attribute.ErrorMessage,
|
||||
RequiredAttribute => ReplaceLabel(templates.Required),
|
||||
RangeAttribute => ReplaceLength(validationContext.Value is string ? templates.String.Range : templates.Number.Range, max: 2),
|
||||
MinLengthAttribute => ReplaceLength(validationContext.Value is string ? templates.String.Min : templates.Number.Min),
|
||||
MaxLengthAttribute => ReplaceLength(validationContext.Value is string ? templates.String.Max : templates.Number.Max),
|
||||
RangeAttribute => ReplaceLength(compareMessage.Range, max: 2),
|
||||
MinLengthAttribute => ReplaceLength(compareMessage.Min),
|
||||
MaxLengthAttribute => ReplaceLength(compareMessage.Max),
|
||||
StringLengthAttribute => ReplaceLength(templates.String.Range, max: 2),
|
||||
_ => attribute.ErrorMessage,
|
||||
};
|
||||
|
||||
if (attribute is RangeAttribute or MinLengthAttribute or MaxLengthAttribute)
|
||||
{
|
||||
validationContext.Value ??= 0;
|
||||
}
|
||||
|
||||
return IsValid(validationContext.Rule.ValidationAttribute, validationContext, out result);
|
||||
}
|
||||
|
||||
private static bool RequiredIsValid(FormValidationContext validationContext, out ValidationResult result)
|
||||
{
|
||||
if (validationContext.Rule.Required == true)
|
||||
|
@ -86,21 +90,22 @@ namespace AntDesign.Internal.Form.Validate
|
|||
{
|
||||
result = null;
|
||||
var rule = validationContext.Rule;
|
||||
var fieldType = validationContext.FieldType;
|
||||
if (rule.Len != null)
|
||||
{
|
||||
ValidationAttribute attribute = null;
|
||||
|
||||
if (rule.Type == FormFieldType.String)
|
||||
if (fieldType == typeof(string))
|
||||
{
|
||||
attribute = new StringLengthAttribute((int)rule.Len);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.String.Len;
|
||||
}
|
||||
if (rule.Type.IsIn(FormFieldType.Number, FormFieldType.Integer, FormFieldType.Float))
|
||||
else if (THelper.IsNumericType(fieldType))
|
||||
{
|
||||
attribute = new NumberAttribute((decimal)rule.Len);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Number.Len;
|
||||
}
|
||||
if (rule.Type == FormFieldType.Array)
|
||||
else if (THelper.IsEnumerable(fieldType))
|
||||
{
|
||||
attribute = new ArrayLengthAttribute((int)rule.Len);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Array.Len;
|
||||
|
@ -127,24 +132,22 @@ namespace AntDesign.Internal.Form.Validate
|
|||
{
|
||||
result = null;
|
||||
var rule = validationContext.Rule;
|
||||
|
||||
var fieldType = validationContext.FieldType;
|
||||
if (rule.Min != null)
|
||||
{
|
||||
ValidationAttribute attribute = null;
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.String))
|
||||
if (fieldType == typeof(string))
|
||||
{
|
||||
attribute = new MinLengthAttribute((int)rule.Min);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.String.Min;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Array))
|
||||
else if (THelper.IsEnumerable(fieldType))
|
||||
{
|
||||
attribute = new MinLengthAttribute((int)rule.Min);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Array.Min;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Number, FormFieldType.Integer, FormFieldType.Float))
|
||||
else if (THelper.IsNumericType(fieldType))
|
||||
{
|
||||
attribute = new NumberMinAttribute((decimal)rule.Min);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Number.Min;
|
||||
|
@ -172,24 +175,23 @@ namespace AntDesign.Internal.Form.Validate
|
|||
{
|
||||
result = null;
|
||||
var rule = validationContext.Rule;
|
||||
var fieldType = validationContext.FieldType;
|
||||
|
||||
if (rule.Max != null)
|
||||
{
|
||||
ValidationAttribute attribute = null;
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.String))
|
||||
if (fieldType == typeof(string))
|
||||
{
|
||||
attribute = new MaxLengthAttribute((int)rule.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.String.Max;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Array))
|
||||
else if (THelper.IsEnumerable(fieldType))
|
||||
{
|
||||
attribute = new MaxLengthAttribute((int)rule.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Array.Max;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Number, FormFieldType.Integer, FormFieldType.Float))
|
||||
else if (THelper.IsNumericType(fieldType))
|
||||
{
|
||||
attribute = new NumberMaxAttribute((decimal)rule.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Number.Max;
|
||||
|
@ -217,24 +219,23 @@ namespace AntDesign.Internal.Form.Validate
|
|||
{
|
||||
result = null;
|
||||
var rule = validationContext.Rule;
|
||||
var fieldType = validationContext.FieldType;
|
||||
|
||||
if (rule.Range != null)
|
||||
{
|
||||
ValidationAttribute attribute = null;
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.String))
|
||||
if (fieldType == typeof(string))
|
||||
{
|
||||
attribute = new StringRangeAttribute((int)rule.Range.Value.Min, (int)rule.Range.Value.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.String.Range;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Array))
|
||||
else if (THelper.IsEnumerable(fieldType))
|
||||
{
|
||||
attribute = new ArrayRangeAttribute((int)rule.Range.Value.Min, (int)rule.Range.Value.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Array.Range;
|
||||
}
|
||||
|
||||
if (rule.Type.IsIn(FormFieldType.Number, FormFieldType.Integer, FormFieldType.Float))
|
||||
else if (THelper.IsNumericType(fieldType))
|
||||
{
|
||||
attribute = new RangeAttribute(rule.Range.Value.Min, rule.Range.Value.Max);
|
||||
attribute.ErrorMessage = validationContext.ValidateMessages.Number.Range;
|
||||
|
@ -300,11 +301,11 @@ namespace AntDesign.Internal.Form.Validate
|
|||
|
||||
private static bool TypeIsValid(FormValidationContext validationContext, out ValidationResult result)
|
||||
{
|
||||
result = null;
|
||||
var rule = validationContext.Rule;
|
||||
|
||||
if (rule.Type == null)
|
||||
{
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -318,14 +319,12 @@ namespace AntDesign.Internal.Form.Validate
|
|||
return false;
|
||||
}
|
||||
|
||||
result = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DefaultFieldIsValid(FormValidationContext validationContext, out ValidationResult result)
|
||||
{
|
||||
if (validationContext.Rule.Type == FormFieldType.Array && validationContext.Rule.DefaultField != null)
|
||||
if (THelper.IsEnumerable(validationContext.FieldType) && validationContext.Rule.DefaultField != null)
|
||||
{
|
||||
Array values = validationContext.Value as Array;
|
||||
|
||||
|
@ -334,6 +333,7 @@ namespace AntDesign.Internal.Form.Validate
|
|||
ValidateMessages = validationContext.ValidateMessages,
|
||||
Rule = validationContext.Rule.DefaultField,
|
||||
FieldName = validationContext.FieldName,
|
||||
FieldType = validationContext.FieldType,
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
|
@ -373,6 +373,7 @@ namespace AntDesign.Internal.Form.Validate
|
|||
ValidateMessages = validationContext.ValidateMessages,
|
||||
DisplayName = validationContext.DisplayName,
|
||||
FieldName = validationContext.FieldName,
|
||||
FieldType = validationContext.FieldType,
|
||||
};
|
||||
|
||||
Array arrValues = validationContext.Value as Array;
|
||||
|
@ -392,6 +393,7 @@ namespace AntDesign.Internal.Form.Validate
|
|||
|
||||
context.Value = arrValues.GetValue(index);
|
||||
context.DisplayName = $"{validationContext.DisplayName}[{index}]";
|
||||
context.FieldType = context.Value.GetType();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -399,6 +401,7 @@ namespace AntDesign.Internal.Form.Validate
|
|||
if (propertyValue != null)
|
||||
{
|
||||
context.Value = propertyValue.GetValue(validationContext.Value);
|
||||
context.FieldType = propertyValue.GetType();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -410,6 +413,7 @@ namespace AntDesign.Internal.Form.Validate
|
|||
continue;
|
||||
}
|
||||
|
||||
context.FieldType = fieldValue.GetType();
|
||||
context.Value = fieldValue.GetValue(validationContext.Value);
|
||||
}
|
||||
|
||||
|
@ -435,19 +439,25 @@ namespace AntDesign.Internal.Form.Validate
|
|||
var rule = validationContext.Rule;
|
||||
|
||||
object[] values = [];
|
||||
string[] labels = null;
|
||||
|
||||
if (rule.Type != FormFieldType.Array && rule.OneOf != null)
|
||||
if (rule.Type != FormFieldType.Array)
|
||||
{
|
||||
values = rule.OneOf;
|
||||
}
|
||||
else if (rule.Enum != null && rule.Enum.IsEnum)
|
||||
{
|
||||
var enumValues = rule.Enum.GetEnumValues();
|
||||
if (rule.OneOf != null)
|
||||
{
|
||||
values = rule.OneOf;
|
||||
}
|
||||
else if (rule.Enum != null)
|
||||
{
|
||||
var enumValues = Enum.GetValues(rule.Enum);
|
||||
values = enumValues.Cast<object>().ToArray();
|
||||
labels = values.Select(v => EnumHelper.GetDisplayName(rule.Enum, v)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (values.Length > 0)
|
||||
{
|
||||
var attribute = new OneOfAttribute(values);
|
||||
var attribute = new OneOfAttribute(values, labels);
|
||||
attribute.ErrorMessage = ReplaceEnum(validationContext.ValidateMessages.Enum);
|
||||
|
||||
if (!IsValid(attribute, validationContext, out ValidationResult validationResult))
|
||||
|
|
|
@ -9,18 +9,27 @@ namespace AntDesign.Internal.Form.Validate
|
|||
{
|
||||
internal object[] Values { get; set; }
|
||||
|
||||
internal OneOfAttribute(object[] values)
|
||||
internal string EnumOptions { get; set; }
|
||||
|
||||
internal OneOfAttribute(object[] values, string[] enumOptions = null)
|
||||
{
|
||||
Values = values;
|
||||
EnumOptions = enumOptions != null ? string.Join(",", enumOptions) : null;
|
||||
}
|
||||
|
||||
public override string FormatErrorMessage(string name)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, JsonSerializer.Serialize(Values));
|
||||
var options = EnumOptions ?? JsonSerializer.Serialize(Values).Trim('[', ']');
|
||||
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, options);
|
||||
}
|
||||
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value is Array)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace AntDesign.Internal.Form.Validate
|
|||
FormFieldType.Regexp => IsRegexp(value),
|
||||
FormFieldType.Array => value is Array,
|
||||
FormFieldType.Object => value is object,
|
||||
FormFieldType.Enum => value is Enum,
|
||||
FormFieldType.Date => value is DateTime,
|
||||
FormFieldType.Url => new UrlAttribute().IsValid(value),
|
||||
FormFieldType.Email => new EmailAddressAttribute().IsValid(value),
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
Float,
|
||||
Array,
|
||||
Object,
|
||||
Enum,
|
||||
Date,
|
||||
Url,
|
||||
Email,
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace AntDesign
|
||||
using System;
|
||||
|
||||
namespace AntDesign
|
||||
{
|
||||
public class FormValidationContext
|
||||
{
|
||||
|
@ -7,6 +9,6 @@
|
|||
public object Value { get; set; }
|
||||
public string FieldName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public Type FieldType { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,9 +270,6 @@ namespace AntDesign.Tests.Form.Validation
|
|||
new object[] { FormFieldType.Float, 100, false },
|
||||
new object[] { FormFieldType.Float, "100", false },
|
||||
|
||||
new object[] { FormFieldType.Enum, FormValidateHelperEnum.None, true },
|
||||
new object[] { FormFieldType.Enum, 100, false },
|
||||
|
||||
new object[] { FormFieldType.Regexp, "\\d", true },
|
||||
new object[] { FormFieldType.Regexp, "^????---))%%%$$3#@^^", false },
|
||||
|
||||
|
@ -406,11 +403,10 @@ namespace AntDesign.Tests.Form.Validation
|
|||
new object[] {
|
||||
new FormValidationRule { Type= FormFieldType.Integer, OneOf = new object[] { 1, 2 } },
|
||||
0,
|
||||
string.Format($"{_defValidateMsgs.Enum}{_customSuffix}", _displayName, JsonSerializer.Serialize(new object[] { 1, 2 }))
|
||||
string.Format($"{_defValidateMsgs.Enum}{_customSuffix}", _displayName, JsonSerializer.Serialize(new object[] { 1, 2 }).Trim('[', ']'))
|
||||
},
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.String }, 123, string.Format($"{_defValidateMsgs.Types.String }{_customSuffix}", _displayName, FormFieldType.String) },
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.Array }, 123, string.Format($"{_defValidateMsgs.Types.Array }{_customSuffix}", _displayName, FormFieldType.Array) },
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.Enum }, 123, string.Format($"{_defValidateMsgs.Types.Enum }{_customSuffix}", _displayName, FormFieldType.Enum) },
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.Number }, "str", string.Format($"{_defValidateMsgs.Types.Number }{_customSuffix}", _displayName, FormFieldType.Number) },
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.Date }, 123, string.Format($"{_defValidateMsgs.Types.Date }{_customSuffix}", _displayName, FormFieldType.Date) },
|
||||
new object[] { new FormValidationRule { Type = FormFieldType.Boolean }, "str", string.Format($"{_defValidateMsgs.Types.Boolean}{_customSuffix}", _displayName, FormFieldType.Boolean) },
|
||||
|
@ -433,7 +429,6 @@ namespace AntDesign.Tests.Form.Validation
|
|||
customValidateMessage.Types.String = $"{customValidateMessage.Types.String}{suffix}";
|
||||
customValidateMessage.Types.Array = $"{customValidateMessage.Types.Array}{suffix}";
|
||||
customValidateMessage.Types.Object = $"{customValidateMessage.Types.Object}{suffix}";
|
||||
customValidateMessage.Types.Enum = $"{customValidateMessage.Types.Enum}{suffix}";
|
||||
customValidateMessage.Types.Number = $"{customValidateMessage.Types.Number}{suffix}";
|
||||
customValidateMessage.Types.Date = $"{customValidateMessage.Types.Date}{suffix}";
|
||||
customValidateMessage.Types.Boolean = $"{customValidateMessage.Types.Boolean}{suffix}";
|
||||
|
@ -472,6 +467,13 @@ namespace AntDesign.Tests.Form.Validation
|
|||
Value = value,
|
||||
FieldName = _fieldName,
|
||||
DisplayName = _displayName,
|
||||
FieldType = rule.Type switch
|
||||
{
|
||||
FormFieldType.String => typeof(string),
|
||||
FormFieldType.Number => typeof(int),
|
||||
FormFieldType.Array => typeof(string[]),
|
||||
_ => typeof(object)
|
||||
}
|
||||
};
|
||||
|
||||
return FormValidateHelper.GetValidationResult(validationContext);
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
);
|
||||
//Act
|
||||
cut.InvokeAsync(() => cut.Instance.Validate());
|
||||
|
||||
//Assert
|
||||
cut.Invoking(c => cut.Find("div.ant-form-item-explain-error"))
|
||||
.Should().Throw<ElementNotFoundException>();
|
||||
|
|
Загрузка…
Ссылка в новой задаче