2010-04-06 9 views
14

Je suis en utilisant un liant de modèle personnalisé dans ASP.NET MVC 2 qui ressemble à ceci:Définition des valeurs ModelState dans le classeur modèle personnalisé

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (controllerContext == null) 
     { 
      throw new ArgumentNullException("controllerContext"); 
     } 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 

     BaseContentObject obj = (BaseContentObject)base.BindModel(controllerContext, bindingContext); 
     if(string.IsNullOrWhiteSpace(obj.Slug)) 
     { 
      // creating new object 
      obj.Created = obj.Modified = DateTime.Now; 
      obj.ModifiedBy = obj.CreatedBy = controllerContext.HttpContext.User.Identity.Name; 
      // slug is not provided thru UI, derivate it from Title; property setter removes chars that are not allowed 
      obj.Slug = obj.Title; 
      ModelStateDictionary modelStateDictionary = bindingContext.ModelState; 
      modelStateDictionary.SetModelValue("Slug", new ValueProviderResult(obj.Slug, obj.Slug, null)); 
... 

Quand je reviens de ce liant dans l'action du contrôleur, mon objet métier qui est fourni comme un paramètre à l'action est correctement modifié (les lignes obj.Created = .... travail).

Toutefois, ModelState n'est pas mis à jour. Je sais que cela parce que je suis requis sur la propriété Slug de mon objet métier et bien que je changeai ModelStateDictionary dans mon classeur de modèle personnalisé, offrant une Slug à (comme vous pouvez le voir ci-dessus), le ModelState.IsValid est encore faux. Si je mets ModelState ["Slug"] dans ma fenêtre Watch dans la session Debug, il dit qu'il a des erreurs (1), donc apparemment il est vide et en tant que tel échoue.

Comment puis-je modifier correctement le ModelState dans le code de liant modèle personnalisé?

Répondre

19

Apparemment, il n'existe aucun moyen de revalider le ModelState une fois que vous avez modifié la valeur d'une clé. L'IsValid reste false car la définition d'une nouvelle valeur sur une clé ne déclenche pas la revalidation.

La solution consiste à supprimer d'abord la clé qui a déclenché IsValid pour qu'elle soit fausse et de la recréer et lui affecter la valeur. Lorsque vous faites cela, le ModelState revalide automatiquement et si tout va bien, IsValid renvoie true.

Comme ceci:

bindingContext.ModelState.Remove("Slug"); 
bindingContext.ModelState.Add("Slug", new ModelState()); 
bindingContext.ModelState.SetModelValue("Slug", new ValueProviderResult(obj.Slug, obj.Slug, null)); 
+1

Votre solution doit être collante à stackoverflow. J'ai cherché et expérimenté haut et bas jusqu'à ce que je trouve celui-ci. Je vous garantis, pas beaucoup de gens savent de ce tour. Tu as sauvé mes jours! Je vous remercie! – Stack0verflow

+0

J'ai essayé votre solution, et cela a fonctionné sorta pour ma situation. Pourriez-vous jeter un oeil à ma question à http://stackoverflow.com/questions/23145780/asp-net-mvc-4-how-to-validate-my-model-in-a-custom-model-binder? Je vous remercie! – Stack0verflow