28

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

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

我可能对下拉列表有误,但根据我的阅读,下拉列表的 Html 对象名称不能与模型中的属性相同,以便正确设置所选值。是否仍然可以通过此解决方法使用数据注释?

谢谢。

4

5 回答 5

73

您可以使用addModelError

ModelState.AddModelError(key,message)

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


看到@Pieter 回答的评论后更新

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

于 2012-04-24T10:56:18.727 回答
16

另一种选择是继承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;
    }
}

编辑:重新阅读问题后,我认为这不适用于这种情况,但我将答案留在这里,以防它帮助其他人。

于 2012-04-24T11:08:37.703 回答
5

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

ModelState.AddModelError();
于 2012-04-24T10:56:08.250 回答
3

是的,你可以做到这一点(你也将使用相同的模型用于 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
    }
}
于 2013-06-24T15:04:17.933 回答
1

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

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

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

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

要将字段设置为无效,只需使用前面提到的 ModelState.AddModelError() 方法。

于 2021-08-05T14:24:48.613 回答