Comment valider uniquement une partie du modèle dans ASP .NET MVC?
J'ai un grand modèle (en gros je veux dire de la classe du modèle contient beaucoup de champs/propriétés et chacun a au moins une validation de l'attribut (comme Required
MaxLength
MinLength
etc)). Au lieu de créer une vue avec beaucoup d'entrées pour un utilisateur de remplir le modèle avec les données que je veux créer plusieurs points de vue où l'utilisateur va remplir une partie du modèle de champs et de passer à l'étape suivante (une sorte de "assistant"). Tout en réorientant entre les étapes que j'ai pas de magasin acquitta modèle objet dans Session
. Quelque chose comme ci-dessous:
Modèle:
public class ModelClass
{
[MaxLength(100)] ...
public string Prop1{get;set;}
[MaxLength(100)] ...
public string Prop2{get;set;}
...
[Required][MaxLength(100)] ...
public string Prop20{get;set;}
}
Contrôleur:
[HttpPost]
public ActionResult Step1(ModelClass postedModel)
{
//user posts only for example Prop1 and Prop2
//so while submit I have completly emty model object
//but with filled Prop1 and Prop2
//I pass those two values to Session["model"]
var originalModel = Session["model"] as ModelClass ?? new ModelClass();
originalModel.Prop1 = postedModel.Prop1;
originalModel.Prop2 = postedModel.Prop2;
Session["model"] = originalModel;
//and return next step view
return View("Step2");
}
[HttpPost]
public ActionResult Step2(ModelClass postedModel)
{
//Analogically the same
//I have posted only Prop3 and Prop4
var originalModel = Session["model"] as ModelClass;
if (originalModel!=null)
{
originalModel.Prop3 = postedModel.Prop3;
originalModel.Prop4 = postedModel.Prop4;
Session["model"] = originalModel;
//return next step view
return View("Step3");
}
return View("SomeErrorViewIfSessionBrokesSomeHow")
}
Step1
vue dispose d'entrées seulement pour Prop1
et Prop2
Step2 vue contient des entrées pour Prop3
et Prop4
etc.
MAIS VOICI LA CHOSE
Lorsque l'utilisateur est sur, par exemple, à l'étape 1, et remplit Prop1 avec une valeur de plus de 100 caractères longueur de la validation côté client fonctionne très bien. Mais, bien sûr , j'ai pour valider cette valeur et sur le côté serveur en contrôleur. Si j'avais plein de modèle que je venais de faire ce qui suit:
if(!ModelState.IsValid) return View("the same view with the same model object");
de sorte que l'utilisateur doit remplir le formulaire à nouveau et de les corriger.
MAIS sur l'étape 1, l'utilisateur a rempli seulement 2 propriétés de 20, et j'ai besoin de les valider. Je ne peux pas utiliser ModelState.IsValid
parce que le modèle de l'état ne sera pas valide. Comme Vous pouvez le voir Prop20
est marqué avec [Required]
attribut, lorsque l'utilisateur soumet Prop1
et Prop2
Prop20
est nul et c'est pourquoi ModelState
est pas valide. Bien sûr, je pourrait permettre à l'utilisateur d'aller à l'étape 2, de remplir toutes les étapes et de valider le modèle de l'état que sur la dernière étape, mais je ne veux pas permettre à l'utilisateur de passer à l'étape 2 si il a rempli l'étape 1 incorrect. Et je veux cette validation dans le contrôleur. La question est donc:
Comment puis-je valider une partie seulement du modèle? Comment puis-je vérifier que seules certaines des propriétés du modèle correspondent à leurs attributs de validation?
source d'informationauteur Dmytro
Vous devez vous connecter pour publier un commentaire.
Une solution possible:
Utilisation ModelState.IsValidField(string key);
Puis à la fin, quand tout est fait usage:
Je pense que la façon la plus élégante est de le faire comme ça:
ou:
Juste pour ajouter à l'existant réponses pour cela. Plutôt que de coder en dur les noms de propriété je voudrais utiliser un attribut d'être ajouté avec le reste de vos attributs de validation le long des lignes de:
Maintenant que nous pouvons obtenir les noms de propriété, sans connaître le modèle lui-même la validation partielle peut être tiré dans une méthode (si vous l'utilisez beaucoup, votre contrôleur de base serait un bon endroit).
Maintenant tout ce que vous devez faire dans votre post d'action serait d'appeler
ValidateStage(postedModel, 1)
MVC Core, ce sera l'équivalent de:
Cependant, je vous recommande tout simplement créer un modèle de vue dans cette instance.
Votre vue partielle modèle pourrait être héritées par votre plus grand modèle de vue de sorte que vous n'aurez pas à répéter vous-même dans le code (SEC principal).
Il vaut mieux éviter de coder en dur les noms de propriété!