Передаем списки значений в контроллеры

В asp.net-mvc как только начинаешь сталкиваться с передачей списков значений в контроллеры, так сразу понимаешь как же все таки неудобно сделан привязчик значений к модели.

Если вы работали в php, то для того чтобы передать список значений — вы писали такие строчки:
1) ?filterIds[0]=1&filterIds[1]=2&filterIds[2]=3, или
2) ?filterIds[1]=2&filterIds[2]=3, или
3)?filterIds[]=1&filterIds[]=2&filterIds[]=3
Но в asp.net-mvc дело обстоит намного иначе. Для меня было это небольшим сюрпризом, потому что до этого я работал с java spring и там я уже сталкивался с чем-то похожим.
Итак рассмотрим каждую строчку по-порядку.
Первая строчка сработает так же как и в php. То есть если в контроллере написать так:

public void GetFilters(List<int> filterIds)
{
}

то в filterIds запишется все так как мы и ожидаем. Но есть все же один подвох. Если мы захотим получить наш список так:

string filterIdsAsString = Request.QueryString["filterIds"];

то в filterIdsAsString оказывается null.
Вторая строчка похоже на первую, за исключением того что там нет первого параметра filterIds[0]=1. Это как раз и ломает всю систему привязки.  То есть в filterIds и filterIdsAsString будет null. Если же будет пропущен второй параметр filterIds[1]=2, то в filterIds будет записано только первое значение, а дальше список как бы поломается.
Третья строчка вообще никаких данных не запишет ни filterIds, ни filterIdsAsString. Но зато если написать такую строчку:

string filterIdsAsString = Request.QueryString["filterIds[]"];

то в filterIdsAsString будет 1,2,3. Исходя из этого можно предположить что параметры записанные как filterIds[] asp.net-mvc понимает как обычный строковый ключ для коллекции QueryString.  Поэтому даже если написать:
?filterIds=1&filterIds=2&filterIds=3, или filterIds]=1&filterIds]=2&filterIds]=3, или ?filterIds!^=1&filterIds!^=2&filterIds!^=3, то по соответствующим ключам filterIds, filterIds] и filterIds!^ получим значение 1,2,3.
Так какой же способ из трех для передачи параметров выбрать? Никакой!
У asp.net есть свой метод передачи списков значений:
4)?filterIds=1&filterIds=2&filterIds=3.
При таком способе в переменные filterIds и filterIdsAsString записывается то что мы и ожидаем. Но мне все равно не понятно почему же тогда htmlhelper-ы Html.EditorFor, Html.TextBoxFor и др. формируют input-ы с указанием атрибутов name по шаблону filterIds[i].
Что хочется еще сказать последний способ так же не обделен минусом.
Допустим мы передаем в контроллер не список значений, а одно значение

public void GetFilters(int filterId)
{
    string filterIdAsString = Request.QueryString("filterId");
}

Все нормально если мы передаем параметры правильно, то есть так:
?filterId=1
Но если в случае каких то недоразумений, мы передали такую строку:
?filterId=1&filterId=2
то в filterId запишется первое значение — 1 (заметьте в php записалось бы второе значение). А в filterIdAsString запишется список значений через запятую — 1,2.
Вот так и приходиться работать со списками значений в asp.net-mvc.
Можно конечно создать свои привязки значений к модели и тем самым настроить работу со списками как в php, но как то не хочется замарачиваться с этим и лучше работать как есть из коробки, только помнить об этих нюансах.

 

 

 

Передаем списки значений в контроллеры: 2 комментария

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>