ASP MVC5-Custom requiredif 验证失败 db.savechanges

ASP MVC5-Custom requiredif validation failing at db.savechanges

首先非常感谢在这里回答问题的大家。我是 asp 框架的新手,从这些答案中学到了很多东西。

我是一个有 2 列的模型

[Required]
public string person1 { get; set; }

[Display(Name = "Service")]
[MaxLength(50)]
[RequiredIf("person1 ", "Yes", ErrorMessage = "Service Field is Required")]
public string Service  { get;set; }

然后我从这个网站使用了 RequiredIf。

   public class RequiredIfAttribute : ValidationAttribute
    {
        private RequiredAttribute innerAttribute = new RequiredAttribute();
        public string DependentUpon { get; set; }
        public object Value { get; set; }

        public RequiredIfAttribute(string dependentUpon, object value)
        {
            this.DependentUpon = dependentUpon;
            this.Value = value;
        }

        public RequiredIfAttribute(string dependentUpon)
        {
            this.DependentUpon = dependentUpon;
            this.Value = null;
        }

        public override bool IsValid(object value)
        {
            return innerAttribute.IsValid(value);
        }
    }

    public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute>
    {
        public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute)
            : base(metadata, context, attribute)
        { }
        public override IEnumerable<ModelValidationResult> Validate(object container)
        { 
            var field = Metadata.ContainerType.GetProperty(Attribute.DependentUpon);
            if (field != null)
            {
                var value = field.GetValue(container, null);
                if ((value != null && Attribute.Value == null) || (value != null && value.Equals(Attribute.Value)))
                {
                    if (!Attribute.IsValid(Metadata.Model))
                        yield return new ModelValidationResult { Message = ErrorMessage };
                }
            }
        }
    }

控制器具有以下操作方法,每次我单击屏幕上的保存按钮时都会执行该方法:-

public ActionResult Create( Person person1)
        {
            if (ModelState.IsValid)
            {

                db.Person.Add(person1);
                try
            {
                db.SaveChanges();
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
            {
                Exception raise = dbEx;
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        string message = string.Format("{0}:{1}",
                            validationErrors.Entry.Entity.ToString(),
                            validationError.ErrorMessage);
                        // raise a new exception nesting  
                        // the current instance as InnerException  
                        raise = new InvalidOperationException(message, raise);
                    }
                }
                throw raise;
            }  
            return RedirectToAction("Index");
        }

        return View(person);
    }

以下是创建视图

<div class="form-group">
                    @Html.LabelFor(model => model.person1 , htmlAttributes: new { @class = "control-label col-md-4" })
                    <div class="col-md-4">
                        @Html.RadioButtonFor(model => model.person1 , "Yes", new { id = "person1Yes" })
                        @Html.Label("Yes", "Yes")

                        @Html.RadioButtonFor(model => model.person1 , "No", new { id = "person1No" })
                        @Html.Label("No", "No")

                    </div>
                </div>


                    <div class="form-group">
                        @Html.LabelFor(model => model.Service, htmlAttributes: new { @class = "control-label col-md-4" })
                        <div class="col-md-4">
                            @Html.EditorFor(model => model.Service, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Service, "", new { @class = "text-danger" })
                        </div>
                    </div>

所以当我点击创建按钮时会发生以下情况:-

1.if person1 有值 "Yes" selected,我在屏幕上收到警告,说服务是强制性的。 2.如果是No,则不显示任何警告。

但是当我 select "NO" 然后点击保存。它在 db.savechanges() 处失败,出现以下错误 "Service Field is Required"。 我不确定为什么它在客户端工作但在保存时失败。

我已经尽量为我这个菜鸟解释了。我可能使用了错误的术语,抱歉。

That is because the validation fired at the browser level (Javascript validation) sees that when No is selected, it passes validation.但是,在服务器端 EF 执行相同的验证。在保存之前检查并查看 person1 在服务器端的值是什么:如果它是空的或者是,那就是问题所在。

在这种情况下,我为我的视图(您拥有的那个)创建了一个模型,为我的 ORM (EF) 创建了一个模型。在 EF 模型中,不要放置 RequiredIf 属性。在保存之前将模型(用于视图)转换为模型(用于 EF),一切都应该是好的。