MVC中模型的条件验证

时间:2013-07-31 12:35:54

标签: asp.net-mvc

我有一个观点&我用于记录的编辑和插入页面的模型。其中一个业务要求是编辑时需要某个字段,而不是新字段。最初在这个特殊功能被添加到文档之前,我有这样的模型:

[Required(ErrorMessage = "*")]
[Range(0.0, (double)decimal.MaxValue)]
[DisplayName("Cost")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public decimal ProposedCost { get; set; }

如果是插入表单,我想删除必需的属性,或者如果是编辑表单,则添加它。什么是更好的方法?我的所有其他验证都是如上所述完成的。或者我可以改变模型状态吗?想法?

修改

我应该澄清的是,他们仍然可以在新的时候插入费用,只是不需要。

4 个答案:

答案 0 :(得分:34)

如果您使用的是MVC3 / .NET4,则可以使用专门用于此类目的的IValidatableObject

引用ScottGu

  

... IValidatableObject接口使您可以执行模型级别   验证,并使您能够提供验证错误消息   具体到整体模型的状态....

你的模特看起来像

public class MyViewModel : IValidatableObject
{
    public long? Id { get; set; }
    public decimal? ProposedCost { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
        if (Id != null && ProposedCost == 0) {
            yield return new ValidationResult("ProposedCost must be provided.");
        }
    }
}

然后在控制器中

[HttpPost]
public ActionResult Submit(MyViewModel model)
{
    if (!ModelState.IsValid) {
        //failed - report an error, redirect to action etc
    }
    //succeeded - save to database etc
}

否则,最干净的解决方案是使用视图模型 - 需要属性的UpdateViewModel和不需要的CreateViewModel

答案 1 :(得分:4)

有MVC Foolproof库:http://foolproof.codeplex.com/

例如,你需要在你的模型中有这样的东西:

[RequiredIfTrue("Required", ErrorMessage = "*")]
[Range(0.0, (double)decimal.MaxValue)]
[DisplayName("Cost")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public decimal ProposedCost { get; set; }

public bool Required { get; set; }

然后,您需要根据模型的形式设置Required属性。

如果您希望执行客户端验证,您还需要表单上的隐藏输入字段来表示Required属性。

希望有帮助...

答案 2 :(得分:3)

您可以使用MVC Foolproof Validation项目中的RequiredIf验证属性。 我已经在项目上使用它来启用你需要的功能。

另一种方法是使用RemoteAttribute并在方法中自己实现逻辑。

答案 3 :(得分:1)

您可以尝试使用以下方式进行验证:

ModelState.Remove("ProposedCost");

或者像这样扩展你的模型:

public class NewModeViewModel : EditModeViewModel
{
   public new decimal ProposedCost { get; set; }
}

并转到编辑视图。