是否可以手动更新ModelState.IsValid?

时间:2012-04-24 10:45:32

标签: asp.net-mvc asp.net-mvc-3

我想尽可能使用内置的验证功能。我也想对CRUD方法使用相同的模型。

但是,由于使用标准模式无法完成下拉列表,因此我必须手动验证它。在post back方法中,我想验证下拉列表并将此结果添加到ModelState,这样我就不必验证使用Data Annotation完成的所有其他参数。是否有可能实现这一目标?

我可能对下拉列表有误,但是从我读到的内容来看,下拉列表的Html对象名称不能与模型中的属性相同,以便正确设置所选值。是否仍然可以使用Data Annotation与此解决方法?

感谢。

5 个答案:

答案 0 :(得分:61)

您可以使用addModelError

ModelState.AddModelError(key,message)

当您使用它时,它将使ModelState无效,因此isValid将返回false。


<强>更新
看到对@ Pieter的答案的评论

如果要排除元素影响isValid()结果,可以在调用isValid()之前使用ModelState.Remove(field)方法。

答案 1 :(得分:15)

另一个选择是在模型中继承IValidatableObject。实现其Validate方法,您可以保留所有其他验证并在此方法中编写您想要的任何代码。注意:您返回一个空的IEnumerable<ValidationResult>表示没有错误。

public class Class1 : IValidatableObject
{
    public int val1 { get; set; }
    public int val2 { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var errors = new List<ValidationResult>();
        if (val1 < 0)
        {
            errors.Add(new ValidationResult("val1 can't be negative", new List<string> { "val2" }));
        }
        if (val2 < 0)
        {
            errors.Add(new ValidationResult("val2 can't be negative", new List<string> { "val2" }));
        }
        return errors;
    }
}
编辑:在重新阅读问题之后,我认为这不适用于这种情况,但我会在这里留下答案,以防它帮助其他人。

答案 2 :(得分:5)

您无法手动设置ModelState.IsValid属性,但可以向ModelState添加消息,以确保IsValid为false。

ModelState.AddModelError();

答案 3 :(得分:2)

是的,你可以实现这一点(你也将使用相同的CRUD方法模型):

示例模型

public class User 
{
    public virtual int Id{ get; set; }
    public virtual Role Role { get; set; }
}
public class Role 
{        
    [Required(ErrorMessage = "Id Required.")]
    public virtual int Id { get; set; }
    [Required(ErrorMessage = "Name Required.")]
    public virtual string Name { get; set; }
}

示例VIEW,在下拉列表中进行验证

@Html.DropDownListFor(m => m.Role.Id, (SelectList)ViewBag.gRoles, "-- Select --")
@Html.ValidationMessageFor(m => m.Role.Id)

CONTROLLER:清除所需的(但不需要)字段

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Creedit(User x)
{
    x.Role = db.RoseSet.Find(x.Role.Id);
    if (x.Role != null)
    {
        ModelState["Role.Name"].Errors.Clear();

    }

    if (ModelState.IsValid)
    {
      // proceed
    }
    else
    {
      // return validation error
    }
}

答案 4 :(得分:1)

可能是更新的方法,因为这是一篇旧帖子,但这可能对未来的读者有所帮助。

可以使用这两种方法将字段设置为有效:

ModelState.ClearValidationState("Password");
ModelState.MarkFieldValid("Password");

需要同时使用两者,因为没有第一个的第二个会给出一个错误,指出状态已经被标记。

要将字段设置为无效,只需使用已引用的 ModelState.AddModelError() 方法。