【问题标题】:Validations in ASP.NET MVC 4 - Validate sum of properties of objects on pageASP.NET MVC 4 中的验证 - 验证页面上对象的属性总和
【发布时间】:2016-12-22 14:49:07
【问题描述】:

我是 MVC 的新手,正在完成一些验证。我已经在模型级别(必需、范围等)完成了我的基本字段验证。我现在正在处理一个页面,该页面本质上是构建一个带有权重的记分卡。我需要每个标准的每个权重加起来为 1。

我不确定是否可以在模型中验证这一点,因为我需要能够在添加这些对象时在数据库中创建它们。在用户继续下一步之前,如何验证这些属性中的每一个的总和为 1?

【问题讨论】:

  • 您可以创建自定义验证。
  • 我的第一个想法是在 ViewModel 上使用 IValidatableObject 接口,它为您提供了一种编写自定义代码的方法,该代码会产生验证错误,就像属性验证代码一样。 stackoverflow.com/questions/3400542/…

标签: c# asp.net asp.net-mvc validation


【解决方案1】:

基本上,对于后端,您需要创建一个自定义验证,该验证可用作要验证的字段的属性。

这是检查“数字是否大于另一个字段”的验证示例。

  [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class NumberGreaterThanAttribute : ValidationAttribute, IClientValidatable
    {
        string otherPropertyName;


        public NumberGreaterThanAttribute(string otherPropertyName, string errorMessage)
            : base(errorMessage)
        {
            this.otherPropertyName = otherPropertyName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationResult validationResult = ValidationResult.Success;


            if (value == null)
                return validationResult;

            try
            {
                // Using reflection we can get a reference to the other date property, in this example the project start date
                var otherPropertyInfo = validationContext.ObjectType.GetProperty(this.otherPropertyName);
                object referenceProperty = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);

                if (referenceProperty == null)
                    return validationResult;

                double referenceProperty_value = System.Convert.ToDouble(referenceProperty, null);
                double currentField_value = System.Convert.ToDouble(value, null);


                if (currentField_value <= referenceProperty_value)
                {
                    validationResult = new ValidationResult(ErrorMessageString);
                }

            }
            catch (Exception ex)
            {

                throw ex;
            }


            return validationResult;
        }


        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            //string errorMessage = this.FormatErrorMessage(metadata.DisplayName);
            string errorMessage = ErrorMessageString;

            // The value we set here are needed by the jQuery adapter
            ModelClientValidationRule numberGreaterThanRule = new ModelClientValidationRule();
            numberGreaterThanRule.ErrorMessage = errorMessage;
            numberGreaterThanRule.ValidationType = "numbergreaterthan"; // This is the name the jQuery adapter will use
            //"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
            numberGreaterThanRule.ValidationParameters.Add("otherpropertyname", otherPropertyName);

            yield return numberGreaterThanRule;
        }
    }

记住:对于自定义/新创建的验证,不会自动启用前端验证。如果你想为前端创建相同的验证规则,你需要创建一个新的前端自定义验证。我通常使用 validate.js 库作为前端。尽管如此,如果您不介意从服务器到客户端来回推送数据,特别是在数据很小的情况下,前端验证并不是严格要求的(但我建议在任何情况下都使用它)。

ViewModel/Model 会在后端收到请求(一般是 POST)时被 modelstate 接收和解析。模型/视图模型应该在需要验证的字段上进行修饰:

    public Int64? AtomicQtyMultiplePurchaseMin { get; set; }


    [NumberGreaterThanAttribute("AtomicQtyMultiplePurchaseMin", "Must be greater than min num. qty. of purchase")]
    public Int64? AtomicQtyMultiplePurchaseMax { get; set; }

我一般将自定义验证类放在以下文件夹中(但你可以将它放在项目中你想要的位置):

【讨论】:

  • 这可能是一个愚蠢的问题,但是您会在哪里添加自定义验证?在控制器中?
  • 你想要的。您可以在名为“mycustomvalidations”的根项目中创建一个文件夹。当您将验证属性应用于视图模型的字段时,请记住使用 using 语句引用验证类。
猜你喜欢
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多