Asp MVC Отримання списку Моделей (Model Binding To List)

13

Програмування Asp.net
Попередній

Наступний

Використовуючи DefaultModelBinder в ASP.NET MVC, Ви можете зв’язати значення на формі (ті що маю атрибут name) з аргументами методу контролера.
Але що, якщо цей аргумент – список, або має складну структуру (клас з різними властивостями)? Ви можете зв’язати відправлену форму з IList ?

Це дуже легко, якщо використовувати масив простих типів. Наприклад, припустимо, що є наступний метод:

public ActionResult UpdateInts(IList<int> ints) {
return View(ints);
}

Можна зібрати дані, просто представляючи зв’язку полів форми з одним і тим же атрибутом name. Наприклад, форма, яка зібрала б аргумент ints в масив(потрібно що б кожен елемент форми мав value цілим числом, по іншому не збере IList<int>, але зможе зібрати в IList<object>):

<form method=”post” action=”/Home/UpdateInts”>
<input type=”text” name=”ints” value=”1″ />
<input type=”text” name=”ints” value=”4″ />
<input type=”text” name=”ints” value=”2″ />
<input type=”text” name=”ints” value=”8″ />
<input type=”submit” />
</form>

Для списку більш складних типів, цей процес стає більш хитрим. Припустимо що є наступний клас Рroduct і метод контролера:

public class Product {
public string Name { get; set; }
public decimal Price { get; set; }
}
//Action method on HomeController
public ActionResult UpdateProducts(IList products) {
return View(products);
}

Для такої складної збірки було введено службове слово Index. Його потрібно використовувати з атрибутом name. На наступному прикладі буде зібрано масив з трьох продуктів:

<form method=”post” action=”/Home/UpdateProducts”>
<input type=”hidden” name=”products.Index” value=”0″ />
<input type=”text” name=”products[0].Name” value=”Beer” />
<input type=”text” name=”products[0].Price” value=”7.32″ />
<input type=”hidden” name=”products.Index” value=”1″ />
<input type=”text” name=”products[1].Name” value=”Chips” />
<input type=”text” name=”products[1].Price” value=”2.23″ />
<input type=”hidden” name=”products.Index” value=”2″ />
<input type=”text” name=”products[2].Name” value=”Salsa” />
<input type=”text” name=”products[2].Price” value=”1.23″ />
<input type=”submit” />
</form>

Потрібно зауважити, що індекс не обов’язково повинен бути числом. Він просто повинен бути рівний для одного і того ж об’єкта. Тобто і так теж можна:

<form method=”post” action=”/Home/UpdateProducts”>
<input type=”hidden” name=”products.Index” value=”cold” />
<input type=”text” name=”products[cold].Name” value=”Beer” />
<input type=”text” name=”products[cold].Price” value=”7.32″ />
<input type=”hidden” name=”products.Index” value=”123″ />
<input type=”text” name=”products[123].Name” value=”Chips” />
<input type=”text” name=”products[123].Price” value=”2.23″ />
<input type=”hidden” name=”products.Index” value=”caliente” />
<input type=”text” name=”products[caliente].Name” value=”Salsa” />
<input type=”text” name=”products[caliente].Price” value=”1.23″ />
<input type=”submit” />
</form>

Я не перевіряв, але може бути буде працювати навіть такий фокус: