Привязка модели к словарю в Нанси
Я не могу привязать JSON к Dictionary<string,string>
в Нэнси.
Этот маршрут:
Get["testGet"] = _ =>
{
var dictionary = new Dictionary<string, string>
{
{"hello", "world"},
{"foo", "bar"}
};
return Response.AsJson(dictionary);
};
Возвращает следующий JSON, как и ожидалось:
{
"hello": "world",
"foo": "bar"
}
Когда я пытаюсь отправить этот точный JSON обратно на этот маршрут:
Post["testPost"] = _ =>
{
var data = this.Bind<Dictionary<string, string>>();
return null;
};
Я получаю исключение:
Значение "[Hello, world] "не относится к типу" System.Строка " и не может будет использоваться в этой общей коллекции.
Можно ли привязать к Dictionary<string,string>
, используя привязку модели по умолчанию Nancys, и если да, то что я здесь делаю неправильно?
1 ответ:
У Нэнси нетвстроенного преобразователя для словарей. Из-за этого вам придется использовать
BindTo<T>()
Вот такvar data = this.BindTo(new Dictionary<string, string>());
Который будет использовать
CollectionConverter
. Проблема в том, что это будет только добавлять строковые значения, поэтому если вы отправите{ "hello": "world", "foo": 123 }
Ваш результат будет содержать только ключ
hello
.Если вы хотите записать все значения в виде строк, даже если они не представлены как таковые, то вам нужно будет использовать пользовательский
IModelBinder
.Это преобразует все значения в строки и возвращают a
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; } }
Нэнси автоматически зарегистрирует это для вас, и вы можете связать свои модели, как обычно.
var data1 = this.Bind<Dictionary<string, string>>(); var data2 = this.BindTo(new Dictionary<string, string>());