2010-02-04 10 views
2

J'essaie de faire ce qui suit. Utilisez le classeur de modèle par défaut pour lier un objet à partir des valeurs de chaîne de requête.
Si cela échoue, j'essaie ensuite de lier l'objet à partir des valeurs de cookie.Personnalisable Modèle-liant qui tire d'un problème de cookie?

Cependant j'utilise des annotations de données sur cet objet et j'ai les problèmes suivants.

  1. S'il n'existe aucun paramètre de chaîne de requête, le classeur de modèle par défaut n'enregistre aucune erreur de validation sur les champs obligatoires. Il ne semble même pas déclencher ces validateurs si la propriété elle-même n'est pas dans la collection de chaînes de requête. Comment puis-je changer ce comportement? Je voudrais que les champs requis soient des erreurs s'ils ne sont pas dans la chaîne de requête.
  2. Si j'ai des erreurs de validation de modèle, je voudrais charger le modèle à partir du cookie, puis revalider l'objet. Je ne suis pas sûr de savoir comment obtenir le classeur modèle pour valider un objet que j'ai moi-même peuplé.

Voici ce que j'ai jusqu'à présent.

public class MyCarBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var myCar = base.BindModel(controllerContext, bindingContext); 

     if (!bindingContext.ModelState.IsValid) 
     { 
      myCar = MyCar.LoadFromCookie(); 
      // Not sure what to do to revalidate 
     } 

     return myCar; 
    } 
} 

Une aide pour mieux se comporter adéquatement serait grandement appréciée.

+0

Je vois la partie 1 de ma question est résolue par la nouvelle version de asp.net mvc 2. – Jeff

+0

Principalement intéressé par la façon de le faire manuellement la validation du modèle après chargement de l'objet à partir du cookie. – Jeff

Répondre

5

Eh bien, je l'ai résolu moi-même. Poster la solution ici au cas où quelqu'un aurait un commentaire ou pourrait vouloir l'utiliser.

public class MyCarBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var queryStringBindingContext = new ModelBindingContext() 
     { 
      FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix, 
      ModelMetadata = bindingContext.ModelMetadata, 
      ModelName = bindingContext.ModelName, 
      PropertyFilter = bindingContext.PropertyFilter, 
      ValueProvider = new QueryStringValueProvider(controllerContext), 
      ModelState = new ModelStateDictionary() 
     }; 

     var myCar = base.BindModel(controllerContext, queryStringBindingContext); 

     if (queryStringBindingContext.ModelState.IsValid) 
      return myCar; 

     // try to bind from cookie if query string is invalid 
     var cookieHelper = new Helpers.ControllerContextCookieHelper(controllerContext); 
     NameValueCollection nvc = cookieHelper.GetCookies(Helpers.CookieName.MyCar); 

     if (nvc == null) 
     { 
      bindingContext.ModelState.Merge(queryStringBindingContext.ModelState); 
      return myCar; 
     } 

     var cookieBindingContext = new ModelBindingContext() 
     { 
      FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix, 
      ModelMetadata = bindingContext.ModelMetadata, 
      ModelName = bindingContext.ModelName, 
      PropertyFilter = bindingContext.PropertyFilter, 
      ValueProvider = new NameValueCollectionValueProvider(nvc, CultureInfo.InvariantCulture), 
      ModelState = new ModelStateDictionary() 
     }; 

     var myCarFromCookie = base.BindModel(controllerContext, cookieBindingContext); 

     if (cookieBindingContext.ModelState.IsValid) 
     { 
      MyCar temp = myCarFromCookie as MyCar; 
      if (temp != null) 
       temp.FromCookie = true; 

      return myCarFromCookie; 
     } 
     else 
     { 
      bindingContext.ModelState.Merge(queryStringBindingContext.ModelState); 
      return myCar; 
     } 
    } 
}