如果工作正常,我有一个自定义的Required。然后我需要一个RangedIf-Required,如果另一个项目是某个值,并且它需要在一个范围内。这确实有效,但不会将错误隐藏起来。我认为由于";返回新的ValidationResult";。有没有一种方法可以在我丢失的自定义属性中抛出错误,并将其链接回文本框?
Ranged,如果读起来像这样:我想看的值,我想让它需要的值,范围的最小值和最大值。
public string IsMonetized { get; set; }
// [RequiredIf("IsMonetized", "Yes", "Please Enter a Value")]
// [Range(1, double.MaxValue, ErrorMessage = "Please Enter an Amount greater than 0")]
[RangedIf("IsMonetized", "Yes", 1, 200)]
public double MaxAmount { get; set; }
//[Range(1, 200, ErrorMessage = "Please Enter an Amount greater than 0")]
[RangedIf("IsMonetized", "Yes", 1, 200)]
public double? AnnualAmount { get; set; }
public class RangedIfAttribute : RequiredAttribute
{
private String PropertyName { get; set; }
private Object DesiredValue { get; set; }
private double max { get; set; }
private double min { get; set; }
public RangedIfAttribute(String propertyName, Object desiredvalue, double Min, double Max)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
min = Min;
max = Max;
}
public RangedIfAttribute(String propertyName, Object desiredvalue, double Min, double Max, String Errormessage)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
ErrorMessage = Errormessage;
min = Min;
max = Max;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
Object instance = context.ObjectInstance;
Type type = instance.GetType();
Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
try
{
if (proprtyvalue == null)
{
if (DesiredValue == null)
{
if (min <= (double)value && (double)value <= max)
{
return base.IsValid(value, context); // Null was intended , and value in range - Valid
}
}
}
else if (proprtyvalue.ToString().Equals(DesiredValue))
{
if (min <= (double)value && (double)value <= max)
{
return base.IsValid(value, context); // desired = property value, and value in range - Valid
}
}
// This should submit Not Valid
return new ValidationResult(this.FormatErrorMessage(context.DisplayName));
}
catch
{
// this should submit not valid - the required item is null
return new ValidationResult($"Value must be within the range of {min} and {max}");
}
}
}
我试着浏览了我能找到的所有自定义属性信息,但似乎没有什么有用的。Validate.Success可以发送成功的验证,但似乎没有自动失败(Validate.Failure(。对于属性系统来说,这似乎是一个过度站点。
两个框上的框都没有立即执行任何操作,也没有标记,但底部的验证摘要将显示:
MaxAmount字段是必需的。-"最大金额字段"由于与正确的if逻辑不匹配而跌至底部。
值必须在1到200的范围内-年度金额将命中try/catch,因为它为null并抛出错误。
同样,它会阻止表单提交,但没有指示哪个框(通常在验证失败时突出显示红色(无法验证。
您的属性需要从ValidationAttribute继承。它包含一个名为ErrorMessage的属性,该属性可以在构造函数中设置。
下面是一个属性示例,用于验证日期是否总是在未来。
[AttributeUsage(AttributeTargets.Property)]
public sealed class FromBeforeAttribute : ValidationAttribute
{
public FromBeforeAttribute()
{
ErrorMessage = "The date cannot be in the past";
}
public override bool IsValid(object? value)
{
if (value is null)
{
return false;
}
var result = DateTime.TryParse(value.ToString(), out DateTime newValue);
return result && newValue != default && DateTime.Compare(DateTime.Now, newValue) > 0;
}
}
;"修复";这是一条虚假退货的线路吗:
return new ValidationResult($"Value must be within the range of {min} and {max}", new[] { context.MemberName });
基本上,这允许系统链接回需要标记的输入框,同时您可以为每个失败区域发送自定义消息。我最下面的一个可以读";没有空值";但让他们在A和B之间发言听起来更好。
这是成品:
[Required(ErrorMessage = "Please Select an Option")]
public string IsMonetized { get; set; }
[RangedIf("IsMonetized", "Yes", 1, 200)]
public double? AnnualAmount { get; set; }
public class RangedIfAttribute : RequiredAttribute
{
private String PropertyName { get; set; }
private Object DesiredValue { get; set; }
private double max { get; set; }
private double min { get; set; }
public RangedIfAttribute(String propertyName, Object desiredvalue, double Min, double Max)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
min = Min;
max = Max;
}
public RangedIfAttribute(String propertyName, Object desiredvalue, double Min, double Max, String Errormessage)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
ErrorMessage = Errormessage;
min = Min;
max = Max;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
Object instance = context.ObjectInstance;
Type type = instance.GetType();
Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
try
{
if (proprtyvalue == null)
{
if (DesiredValue == null)
{
if (min <= (double)value && (double)value <= max)
{
return base.IsValid(value, context); // Null was intended , and value in range
}
else
{
return new ValidationResult($"Value must be within the range of {min} and {max}", new[] { context.MemberName }); // null was intended but value not in range
}
}
else
{
return ValidationResult.Success; //property value is null - needs to be selected first - do not trigger
}
}
else if (proprtyvalue.ToString().Equals(DesiredValue))
{
if (min <= (double)value && (double)value <= max)
{
return base.IsValid(value, context); // property = intended value and value in range
}
else
{
return new ValidationResult($"Value must be within the range of {min} and {max}", new[] { context.MemberName }); //property = inteded value but not in range
}
}
return ValidationResult.Success; //not required
}
catch
{
// most likely a null value
return new ValidationResult($"Value must be within the range of {min} and {max}", new[] { context.MemberName });
}
}
}