asp.net-mvc MVC中模型的条件验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17970584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Conditional validation on model in MVC
提问by Seth
I have a view & model that I use for both the edit and the insert page for a record. One of the business requirements is that a certain field is required on edit but not on new. Originally before this particular feature was added to the docket, i had the model like so:
我有一个视图和模型,可用于记录的编辑和插入页面。业务需求之一是编辑需要某个字段,但新字段不需要。最初,在将此特定功能添加到摘要之前,我有这样的模型:
[Required(ErrorMessage = "*")]
[Range(0.0, (double)decimal.MaxValue)]
[DisplayName("Cost")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public decimal ProposedCost { get; set; }
I would like to either remove the required property if it is an insert form, or add it if an edit form. What is the better approach? All my other validation is done like above. Or can I alter the model state? Thoughts?
如果是插入表单,我想删除所需的属性,或者如果是编辑表单,则添加它。什么是更好的方法?我所有的其他验证都像上面一样完成。或者我可以改变模型状态吗?想法?
EDIT
编辑
Something I should clarify is that they are still permitted to insert a cost on new, just not required.
我应该澄清的一点是,他们仍然可以在新的上插入成本,只是不需要。
回答by andreister
If you're on MVC3/.NET4, you can use IValidatableObjectwhich exists specifically for such purposes.
如果您使用的是 MVC3/.NET4,您可以使用IValidatableObjectwhich 专门用于此类目的。
Quoting ScottGu,
引用ScottGu 的话,
...The IValidatableObject interface enables you to perform model-level validation, and enables you to provide validation error messages specific to the state of the overall model....
... IValidatableObject 接口使您能够执行模型级验证,并使您能够提供特定于整个模型状态的验证错误消息....
You model would look like
你的模型看起来像
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.");
}
}
}
and then in the controller,
然后在控制器中,
[HttpPost]
public ActionResult Submit(MyViewModel model)
{
if (!ModelState.IsValid) {
//failed - report an error, redirect to action etc
}
//succeeded - save to database etc
}
Otherwise, the most clean solution would be to use view models - UpdateViewModelwhere the property is required, and CreateViewModelwhere it's not required.
否则,最干净的解决方案是使用视图模型 -UpdateViewModel需要属性的CreateViewModel地方和不需要的地方。
回答by pkunal7
There is the MVC Foolproof library: http://foolproof.codeplex.com/
有 MVC Foolproof 库:http: //foolproof.codeplex.com/
For example you would need to have something like this in your model:
例如,你需要在你的模型中有这样的东西:
[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; }
You would then need to set the Requiredproperty based on which form the model is going to.
然后,您需要Required根据模型将要使用的表单来设置属性。
You will also need a hidden input field on the form to represent the Requiredproperty if you wish to perform client side validation.
Required如果您希望执行客户端验证,您还需要表单上的隐藏输入字段来表示属性。
Hope that helps...
希望有帮助...
回答by christophano
You could use the RequiredIfvalidation attribute from the MVC Foolproof Validationproject.
I've used it on projects to enable just the functionality you require.
您可以使用MVC Foolproof Validation项目中的RequiredIf验证属性。我已经在项目中使用它来启用您需要的功能。
An alternative would be to use the RemoteAttributeand implement the logic yourself in a method.
另一种方法是RemoteAttribute在方法中自己使用和实现逻辑。
回答by Daniele
You can try on validation with:
您可以尝试使用以下方法进行验证:
ModelState.Remove("ProposedCost");
Or extending your model like this:
或者像这样扩展你的模型:
public class NewModeViewModel : EditModeViewModel
{
public new decimal ProposedCost { get; set; }
}
and passing to the edit view.
并传递到编辑视图。

