16

我有一个视图和模型,用于记录的编辑和插入页面。业务需求之一是编辑时需要某个字段,而新建时不需要。最初在将此特定功能添加到案卷之前,我有这样的模型:

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

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

编辑

我应该澄清的是,他们仍然可以在新产品上插入成本,只是不需要。

4

4 回答 4

36

如果您使用的是 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不需要的地方。

于 2013-07-31T12:52:05.240 回答
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如果您希望执行客户端验证,您还需要表单上的隐藏输入字段来表示属性。

希望有帮助...

于 2013-07-31T12:52:06.587 回答
3

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

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

于 2013-07-31T12:45:55.313 回答
1

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

ModelState.Remove("ProposedCost");

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

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

并传递到编辑视图。

于 2013-07-31T12:49:40.863 回答