2013-07-31 70 views
15

我有一个模型,我用于记录的编辑和插入页面。其中一项业务要求是编辑时需要某个字段,而不是新的字段。原来之前这个特殊的功能被添加到案卷,我有模型,像这样:MVC模型的条件验证

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

我想要么删除所需的属性,如果它是一个插入的形式,或者,如果编辑的形式添加。什么是更好的方法?我所有的其他验证都按照上面的方式完成或者我可以改变模型状态?思考?

编辑

东西我要澄清的是,他们仍然被允许插入新的成本,就不是必需的。

回答

32

如果您使用的是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它不是必需的。

+0

我试过这个,但仍然能够保存编辑记录没有建议的成本。我放置了一个断点,并打了Validationresult。思考? – Seth

+0

你确定你检查过'ModelState.IsValid'吗?我更新了答案以示例。另外请注意,如果我们不允许设置ProposedCost,则ProposedCost必须为空。 – andreister

+0

是的,我错过了,很好。添加的其他属性在后台自动进行客户端检查。无论如何,我可以挖掘到?这当然超出了我原来的问题范围。 – Seth

3

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

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

+3

我个人不喜欢'RequiredIf',因为它不是类型安全的 - 你必须写'[RequiredIf( “SomeProperty”,值,...)]',它意味着编译器不会警告你'SomeProperty'被重命名,但旧名称被卡在属性 – andreister

+0

@andreister中,你可以使用'[RequiredIf(nameof(SomeProperty),value,...)]''它可以编译实时验证并应对“SomeProperty”的重命名 –

+0

非常真实@JamesCulshaw--我最喜欢的C#6功能之一,因为它有助于确切的场景。 – christophano

0

您可以尝试与验证:

ModelState.Remove("ProposedCost"); 

或延长你的模型是这样的:

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

,并传递给编辑视图。

4

还有就是MVC万全库: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属性。

希望帮助...