验证取决于其他字段的值(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 "";
            }
        }
    }

验证取决于其他字段的值(MVC)

这里有两种可能的方法。

四有效对象

正如用户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...");
        }
    }