2012-04-24 80 views
16

我想尽可能使用内置的验证功能。我也想为CRUD方法使用相同的模型。是否可以手动更新ModelState.IsValid?

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

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

谢谢。

回答

49

可以使用addModelError

ModelState.AddModelError(key,message) 

当您使用,它将无效的ModelState所以isValid将返回false。


更新
看到注释@彼得的回答

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

+0

+1,用于提供链接addModelError – 2012-04-24 11:07:26

+10

ModelState.Remove(field)就是我所需要的!谢谢。 – 2012-04-24 12:55:32

+1

如果您在模型上使用IValidatableObject,请注意此问题,因为此属性验证失败时不会运行该验证,但如果仅在您的Remove()属性失败时再次运行,则表明您的错误有效结果。 – pauloya 2012-11-26 16:23:46

5

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

ModelState.AddModelError(); 
+0

这不是我正在寻找的。我正在寻找的是类似于相反的东西:ModelState.IgnoreModelError(“somekey”)忽略属性的任何验证错误,以somekey作为关键字,以便ModelState.IsValid将继续评估所有其他参数。我之所以需要这样做,是因为我试图为所有CRUD方法创建一个模型,但下拉列表问题要求我在“创建vs更新”中以不同的方式处理下拉列表。需要的数据注释可以在创建而不是更新中使用。对于更新,我将不得不验证它... – 2012-04-24 12:11:16

+0

手动,但我不希望其自动验证错误导致整个模型无效。 – 2012-04-24 12:13:11

+0

当然,我可以通过使用更新的不同模型来解决问题。谢谢。 – 2012-04-24 12:14:32

11

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

编辑:在重新阅读的问题后,我不认为这适用于这种情况,但我离开这里的答案的情况下,它可以帮助别人。

+0

谢谢。这是更复杂情况的一种选择。感谢领先。 – 2012-04-24 12:56:28

+0

我个人比选择的问题更喜欢这个选项。它保留了模型内部验证模型的逻辑,而不是控制器。 – ohyeah 2016-09-26 11:27:15

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; } 
} 

示例视图与验证的下拉列表

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

控制器:清除所需的(但不是必需的)字段

[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 
    } 
} 
+1

非常感谢ModelState [“Role.Name”]。Errors.Clear() – InkHeart 2016-07-04 02:24:58

相关问题