【问题标题】:Model Validation not working with all properties模型验证不适用于所有属性
【发布时间】:2014-12-31 04:13:56
【问题描述】:

我有以下 ViewModel:

 public class MyViewModel:IValidatableObject
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public DateTime? Birthday { get; set; }

        public int Status { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (string.IsNullOrWhiteSpace(Name))
                yield return new ValidationResult("Please fill the name", new string[] { "Name" });

            if (Birthday.HasValue == false)
                yield return new ValidationResult("Please fill the birthday", new string[] { "Birthday" });

            if(Status <= 0)
                yield return new ValidationResult("Please fill the status", new string[] { "Status" });
        }
    }

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Birthday,Status")] MyViewModel myViewModel)
{
    if (ModelState.IsValid)
    {
        db.MyViewModels.Add(myViewModel);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(myViewModel);
}

我想同时显示所有验证消息,但是它显示第一个状态,然后显示其他两个属性。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-5 data-annotations


    【解决方案1】:

    这是由于验证发生的顺序。首先,ModelBinder 完成了它的工作,如果通过了,因为您已经通过实现 IValidatableObject 创建了一个自我验证的视图模型,所以会调用 Validate 方法。在第一个屏幕截图中,模型绑定过程失败,因此永远不会调用 Validate。在第二个屏幕截图中,模型绑定成功,但 Validate() 失败。

    您可以通过使用 DataAnnotations 而不是像这样实现 IValidatableObject 来解决这个问题:

        public class MyViewModel:IValidatableObject
        {
            public int Id { get; set; }
            [Required]
            public string Name { get; set; }
            [Required]
            public DateTime Birthday { get; set; }
            [Required, Range(0, Int32.MaxValue)]
            public int Status { get; set; }
        }
    

    【讨论】:

    • 保持 IValidatableObject 是否可以达到相同的结果?
    • 如果您通过 Validate() 方法完成了所有验证,是的。只需将视图模型上的所有属性设为可选,然后在 Validate() 中编写规则即可。
    • 更改为公共 int?状态{获取;放; } 它只显示姓名和生日验证消息。 Ps:我所有的验证都是使用 IValidatableObject 中的 Valida 完成的
    • 对,但此时您需要检查 Status.HasValue 并自己手动添加验证错误,就像您当前对 Birthday 属性所做的那样。
    • 它几乎可以工作了。我唯一的问题是当我更改为 Html.DropDownListFor(x=>x.Status) 例如。它仍然首先验证状态
    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多