验证取决于其他字段的值(MVC)
本文关键字:MVC 取决于 其他 字段 验证 | 更新日期: 2023-09-27 17:57:37
我有3个输入框供某人输入电话号码。一个用于区号(3位),一个用于前缀(3位数字),另一个用于后缀(4位数字)。我想在保存之前验证3个字段的总和是否等于10。如何使用数据注释来实现这一点?
型号:
public string PhoneNumber
{
get
{
return _phoneNumber;
}
set
{
_phoneNumber = value;
}
}
private string _phoneNumber;
public string Area
{
get
{
try
{
return _phoneNumber.Split(new char[] { '(', ')', '-' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
}
catch
{
return "";
}
}
}
public string Prefix
{
get
{
try
{
return _phoneNumber.Split(new char[] { '(', ')', '-' }, StringSplitOptions.RemoveEmptyEntries)[1].Trim();
}
catch
{
return "";
}
}
}
public string Suffix
{
get
{
try
{
return _phoneNumber.Split(new char[] { '(', ')', '-' }, StringSplitOptions.RemoveEmptyEntries)[2].Trim();
}
catch
{
return "";
}
}
}
这里有两种可能的方法。
四有效对象
正如用户stuartd在评论中提到的,您可以在模型中实现IValidatableObject来进行验证。在您的情况下,您的代码看起来像这样:
public class MyModel : IValidatableObject
{
// Your properties go here
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// You may want to check your properties for null before doing this
var sumOfFields = PhoneNumber.Length + Area.Length + Prefix.Length;
if(sumOfFields != 10)
return new ValidationResult("Incorrect phone number!");
}
}
自定义验证属性
由于您声明要使用数据注释,因此可以实现自定义ValidationAttribute。它会沿着这些路线发展。
public class TotalAttributesLengthEqualToAttribute : ValidationAttribute
{
private string[] _properties;
private int _expectedLength;
public TotalAttributesLengthEqualToAttribute(int expectedLength, params string[] properties)
{
ErrorMessage = "Wrong total length";
_expectedLength = expectedLength;
_properties = properties;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (_properties == null || _properties.Length < 1)
{
return new ValidationResult("Wrong properties");
}
int totalLength = 0;
foreach (var property in _properties)
{
var propInfo = validationContext.ObjectType.GetProperty(property);
if (propInfo == null)
return new ValidationResult($"Could not find {property}");
var propValue = propInfo.GetValue(validationContext.ObjectInstance, null) as string;
if (propValue == null)
return new ValidationResult($"Wrong property type for {property}");
totalLength += propValue.Length;
}
if (totalLength != _expectedLength)
return new ValidationResult(ErrorMessage);
return ValidationResult.Success;
}
}
然后你会选择你的一个属性并像这样实现:
[TotalAttributesLengthEqualTo(10, nameof(PhoneNumber), nameof(Area), nameof(Prefix), ErrorMessage = "The phone number should contain 10 digits")]
public string PhoneNumber
{
get...
请注意,如果编译器不支持C#6.0,则必须将以$开头的字符串更改为字符串。格式,您将不得不用nameof()中的属性名称替换其他硬编码名称。
您可以这样做:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string area = (string)validationContext.ObjectType.GetProperty("Area").GetValue(validationContext.ObjectInstance, null);
string prefix = (string)validationContext.ObjectType.GetProperty("Prefix").GetValue(validationContext.ObjectInstance, null);
string suffix = (string)validationContext.ObjectType.GetProperty("Suffix").GetValue(validationContext.ObjectInstance, null);
if ((area.Length + prefix.Length + suffix.Length) == 10)
{
return ValidationResult.Success;
}
else
{
return new ValidationResult("I will not use DA for this, but there we go...");
}
}
或者先连接值,然后只使用属性值
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string number = (string)value;
if (number.Length == 10)
{
return ValidationResult.Success;
}
else
{
return new ValidationResult("I will not use DA for this, but there we go...");
}
}