2015-05-28 13 views
5

Non riesco a legare JSON a Dictionary<string,string> a Nancy.Collegamento del modello al dizionario <stringa, stringa> in Nancy

Questo percorso:

Get["testGet"] = _ => 
{ 
    var dictionary = new Dictionary<string, string> 
    { 
     {"hello", "world"}, 
     {"foo", "bar"} 
    }; 

    return Response.AsJson(dictionary); 
}; 

restituisce il seguente JSON, come ci si aspettava:

{ 
    "hello": "world", 
    "foo": "bar" 
} 

Quando provo e questo post JSON esatto di nuovo a questo percorso:

Post["testPost"] = _ => 
{ 
    var data = this.Bind<Dictionary<string, string>>(); 
    return null; 
}; 

I ottenere l'eccezione:

Il valore "[Hello, world]" non è di tipo "System.String" e non è possibile utilizzare in questa raccolta generica.

È possibile eseguire il binding a Dictionary<string,string> utilizzando l'associazione modello predefinita di Nancys e, in caso affermativo, cosa sto facendo male qui?

risposta

5

Nancy non ha un built-in converter per i dizionari. A causa di questo avresti bisogno di usare BindTo<T>() in questo modo

var data = this.BindTo(new Dictionary<string, string>()); 

, che utilizzerà il CollectionConverter. Il problema con il fare in questo modo è sarà solo aggiungere valori di stringa, quindi se si invia

{ 
    "hello": "world", 
    "foo": 123 
} 

il risultato conterrà solo la chiave hello.

Se si desidera acquisire tutti i valori come stringhe, anche se non vengono fornite come tali, sarà necessario utilizzare un numero personalizzato IModelBinder.

Questo convertirà tutti i valori in stringhe e restituirà uno Dictionary<string, string>.

public class StringDictionaryBinder : IModelBinder 
{ 
    public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration, params string[] blackList) 
    { 
     var result = (instance as Dictionary<string, string>) ?? new Dictionary<string, string>(); 

     IDictionary<string, object> formData = (DynamicDictionary) context.Request.Form; 

     foreach (var item in formData) 
     { 
      var itemValue = Convert.ChangeType(item.Value, typeof (string)) as string; 

      result.Add(item.Key, itemValue); 
     } 

     return result; 
    } 

    public bool CanBind(Type modelType) 
    { 
     // http://stackoverflow.com/a/16956978/39605 
     if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof (Dictionary<,>)) 
     { 
      if (modelType.GetGenericArguments()[0] == typeof (string) && 
       modelType.GetGenericArguments()[1] == typeof (string)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

Nancy si auto registrare questo per voi e si può legare i vostri modelli come si farebbe normalmente.

var data1 = this.Bind<Dictionary<string, string>>(); 
var data2 = this.BindTo(new Dictionary<string, string>()); 
Problemi correlati