Convalida condizionale sul modello in MVC

Ho una vista e un modello che uso sia per la modifica che per la pagina di inserimento di un record. Uno dei requisiti aziendali è che per la modifica è richiesto un determinato campo ma non un nuovo. Originariamente prima che questa caratteristica particolare venisse aggiunta al docket, avevo il modello in questo modo:

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

Vorrei rimuovere la proprietà richiesta se si tratta di un modulo di inserimento o aggiungerlo se si tratta di un modulo di modifica. Qual è l’approccio migliore? Tutta la mia altra convalida è fatta come sopra. Oppure posso modificare lo stato del modello? Pensieri?

MODIFICARE

Qualcosa che dovrei chiarire è che sono ancora autorizzati a inserire un costo su nuovo, solo non richiesto.

Se si utilizza MVC3 / .NET4, è ansible utilizzare IValidatableObject che esiste specificamente per tali scopi.

Citando ScottGu ,

… L’interfaccia IValidatableObject consente di eseguire la convalida a livello di modello e consente di fornire messaggi di errore di convalida specifici per lo stato del modello generale ….

La tua modella dovrebbe assomigliare

 public class MyViewModel : IValidatableObject { public long? Id { get; set; } public decimal? ProposedCost { get; set; } public IEnumerable Validate(ValidationContext validationContext) { if (Id != null && ProposedCost == 0) { yield return new ValidationResult("ProposedCost must be provided."); } } } 

e poi nel controller,

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

In caso contrario, la soluzione più pulita sarebbe utilizzare i modelli di visualizzazione: UpdateViewModel cui è richiesta la proprietà e CreateViewModel dove non è richiesto.

C’è la libreria Foolproof MVC: http://foolproof.codeplex.com/

Ad esempio, dovresti avere qualcosa di simile nel tuo modello:

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

Dovresti quindi impostare la proprietà Required in base a quale modulo verrà utilizzato il modello.

Sarà inoltre necessario un campo di input nascosto nel modulo per rappresentare la proprietà Required se si desidera eseguire la convalida lato client.

Spero possa aiutare…

È ansible utilizzare l’attributo di convalida RequiredIf dal progetto di convalida Foolproof MVC . L’ho usato su progetti per abilitare solo la funzionalità richiesta.

Un’alternativa sarebbe utilizzare RemoteAttribute e implementare la logica da soli in un metodo.

Puoi provare con la convalida con:

 ModelState.Remove("ProposedCost"); 

O estendendo il tuo modello in questo modo:

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

e passando alla vista di modifica.