2010-02-24 8 views
5

J'essaye de migrer vers ASP.Net MVC 2 et rencontrer quelques problèmes. En voici un: J'avais besoin de lier directement un Dictionnaire comme résultat d'une publication.MVC 2, IModelBinder & ValueProvider changements

Dans ASP.Net MVC 1, il a parfaitement fonctionné en utilisant une coutume IModelBinder:

/// <summary> 
/// Bind Dictionary<int, int> 
/// 
/// convention : <elm name="modelName_key" value="value"></elm> 
/// </summary> 
public class DictionaryModelBinder : IModelBinder 
{ 
    #region IModelBinder Members 

    /// <summary> 
    /// Mandatory 
    /// </summary> 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     IDictionary<int, int> retour = new Dictionary<int, int>(); 

     // get the values 
     var values = bindingContext.ValueProvider; 
     // get the model name 
     string modelname = bindingContext.ModelName + '_'; 
     int skip = modelname.Length; 

     // loop on the keys 
     foreach(string keyStr in values.Keys) 
     { 
      // if an element has been identified 
      if(keyStr.StartsWith(modelname)) 
      { 
       // get that key 
       int key; 
       if(Int32.TryParse(keyStr.Substring(skip), out key)) 
       { 
        int value; 
        if(Int32.TryParse(values[keyStr].AttemptedValue, out value)) 
         retour.Add(key, value); 
       } 
      } 
     } 
     return retour; 
    } 

    #endregion 
} 

Il a travaillé en paire avec un certain HtmlBuilder intelligent qui affiche le dictionnaire de données.

Le problème que je rencontre est maintenant que ValueProvider est pas un dictionnaire <> plus, il est un IValueProvider qui ne permettent d'obtenir des valeurs dont le nom est connu

public interface IValueProvider 
{ 
    bool ContainsPrefix(string prefix); 
    ValueProviderResult GetValue(string key); 
} 

C'est vraiment pas cool que je ne peux pas effectuer mon analyse intelligente ...

question:

  1. y at-il une autre façon d'obtenir toutes les clés?
  2. Connaissez-vous une autre façon de lier une collection d'éléments HTML à un dictionnaire

Merci pour vos suggestions

O.

+0

Voir ici: http://stackoverflow.com/questions/2290473/ivalueprovider-in-mvc-2-rc-2/2290520 # 2290520 – tvanfosson

Répondre

1

Je ne pense pas que vous serez en mesure de le faire De cette façon plus dans MVC 2.
Sinon, vous pouvez étendre DefaultModelBinder et remplacer une de ses méthodes virtuelles comme GetModelProperties, puis modifier le ModelName dans le ModelBindingContext. Une autre option consisterait à implémenter un MetadataProvider personnalisé pour votre type de dictionnaire, vous pouvez également y changer le nom du modèle.

2

Bien que cette question ait été marquée 'répondu', je pense que ce qui suit pourrait vous être utile. J'ai eu le même problème et j'ai regardé le code source du System.Web.Mvc.DefaultValueProvider. Il obtient ses valeurs à partir de RouteData, de la chaîne de requête ou d'une soumission de formulaire de demande (dans cet ordre précis). Pour recueillir toutes les clés (ce qui est ce que vous demandez dans votre première question), j'ai écrit la méthode d'assistance suivante.

private static IEnumerable<string> GetKeys(ControllerContext context) 
{ 
    List<string> keys = new List<string>(); 
    HttpRequestBase request = context.HttpContext.Request; 
    keys.AddRange(((IDictionary<string, 
     object>)context.RouteData.Values).Keys.Cast<string>()); 
    keys.AddRange(request.QueryString.Keys.Cast<string>()); 
    keys.AddRange(request.Form.Keys.Cast<string>()); 
    return keys; 
} 

Vous pouvez utiliser cette méthode pour énumérer les clés:

foreach (string key in GetKeys(controllerContext)) 
{ 
    // Do something with the key value. 
} 
+0

Je vois maintenant que mon approche ne permet pas de tester facilement un classeur de modèle personnalisé puisque le code GetKeys accède directement à Request.Form et Request.QueryString. Je vais vérifier si je peux améliorer cela. – Jeroen