【问题标题】:validation depending on the values of other fields (MVC)验证取决于其他字段的值(MVC)
【发布时间】:2016-07-18 23:24:22
【问题描述】:

我有 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 "";
            }
        }

    }

【问题讨论】:

标签: c# regex validation


【解决方案1】:

这里有两种可能的方法。

IValidatableObject

正如用户 stuartd 在 cmets 中提到的,您可以在模型中实现 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,则必须将以 $ 开头的字符串更改为 string.Format,并且必须将 nameof() 中的属性名称替换为硬编码名称。

【讨论】:

  • 你先生....你是真正的MVP。一个简单的问题,用“nameof() 中的属性名称替换它们的硬编码名称”是什么意思?
  • nameof 表达式在编译时被评估为传递给它的成员的字符串表示形式。例如,nameof(PhoneNumber) 将被评估为字符串“PhoneNumber”。您可以简单地使用“PhoneNumber”而不是 nameof(PhoneNumber)。使用 nameof 的主要优点是它会更容易维护,以防您将来需要更改该属性名称。
  • 我明白了...感谢您的解释。但是,在声明名称时,我收到一条错误消息,告诉我“非静态字段、方法或属性 'RxCard.DataObjects.Pharmacy.Area' 需要对象引用”。抱歉,我是 .net 的新手。
  • 如果不查看您的代码,我无法肯定地回答您。但看起来您正试图在静态方法中调用 .Area 。如果这发生在 nameof(Area) 和另一个 nameof 中,请尝试将它们更改为 nameof(Pharmacy.Area)。否则,我会寻找尝试使用 Area 作为实例属性的静态方法。
【解决方案2】:

你可以这样做:

    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...");
        }
    }

【讨论】:

    猜你喜欢
    • 2016-01-20
    • 2021-07-08
    • 1970-01-01
    • 2019-02-05
    • 2016-06-08
    • 2016-12-28
    • 1970-01-01
    • 2017-09-08
    相关资源
    最近更新 更多