2010-02-24 9 views
5

Ich versuche, zu ASP.Net MVC 2 zu migrieren und einige Probleme zu treffen. Hier ist eine: Ich musste direkt ein Dictionary als Ergebnis einer Ansicht Post binden.MVC 2, IModelBinder & ValueProvider ändert sich

In ASP.Net MVC 1 es funktionierte perfekt einem benutzerdefinierten IModelBinder mit:

/// <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 
} 

Es in Paar mit einigen intelligenten HtmlBuilder gearbeitet, die Wörterbuch der Daten angezeigt.

Das Problem, das ich jetzt treffen ist, dass Valueprovider ist kein Wörterbuch <> mehr, es ist ein IValueProvider ist, die nur erlauben Werte zu erhalten, dessen Name

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

Dieses bekannt ist, ist wirklich nicht cool, wie ich kann nicht führen meine intelligente Parsing ...

Frage:

  1. gibt es einen anderen Weg, um alle Schlüssel zu bekommen?
  2. Kennen Sie einen anderen Weg, um eine Sammlung von HTML-Elementen zu einem Wörterbuch

Vielen Dank für Ihre Anregungen

O.

+0

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

Antwort

1

ich Sie werden in der Lage nicht denken, zu binden, zu tun es in MVC 2 so weiter.
Alternativ können Sie DefaultModelBinder erweitern und eine seiner virtuellen Methoden wie GetModelProperties überschreiben und dann den ModelName innerhalb des ModelBindingContext ändern. Eine andere Option wäre, einen benutzerdefinierten MetadataProvider für Ihren Dictionary-Typ zu implementieren, Sie können den Modellnamen auch dort ändern.

2

Obwohl diese Frage als "beantwortet" markiert wurde, kann das folgende hilfreich sein. Ich hatte das gleiche Problem und sah mir den Quellcode von System.Web.Mvc.DefaultValueProvider an. Er erhält seine Werte aus der RouteData, der Query-Zeichenfolge oder aus einer Anfrageformular-Anfrage (in dieser Reihenfolge). Um alle Schlüssel zu sammeln (was Sie in Ihrer ersten Frage verlangen) habe ich die folgende Hilfsmethode geschrieben.

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

können Sie diese Methode verwenden, über die Tasten aufzuzählen:

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

Ich sehe jetzt, dass mein Ansatz das einfache Testen eines benutzerdefinierten Modellbinders nicht ermöglicht, da der GetKeys-Code direkt auf Request.Form und Request.QueryString zugreift. Ich werde prüfen, ob ich das verbessern kann. – Jeroen