Как вы обрабатываете вывод динамически сгенерированной формы в ASP.NET MVC? - PullRequest
4 голосов
/ 21 октября 2008

Допустим, вы создаете форму с использованием ASP.NET MVC, которая имеет динамическое число элементов формы.

Например, вам нужен флажок для каждого продукта, и количество продуктов меняется день ото дня.

Как бы вы справились с отправкой этих данных формы обратно в контроллер? Вы не можете установить параметры для метода действия, потому что вы не знаете, сколько значений формы будет возвращено.

Ответы [ 4 ]

5 голосов
/ 21 октября 2008

Просто присвойте каждому флажку уникальное значение имени:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" 
 name="<%= "approveCheck" + recordId %>" type="checkbox" />

Затем проанализируйте список значений формы в действии после отправки:

foreach (var key in Request.Form.Keys)
    {
        string keyString = key.ToString();
        if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase))
        {
            string recNum = keyString.Substring(12, keyString.Length - 12);

            string approvedKey = Request.Form["approveCheck" + recNum];
            bool approved = !String.IsNullOrEmpty(approvedKey);
            // ...

Вам не нужно передавать значения формы в качестве аргументов; Вы можете просто получить их из Request.Form.

Еще один вариант: написать подшивку модели, чтобы изменить список на пользовательский тип для отправки формы.

2 голосов
/ 21 октября 2008

В зависимости от используемых вами связующих, это должно работать:

<%var i = 0;
  foreach (var product (IList<ProductSelection>)ViewData["products"]) {%>
      <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%>
      <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%>
      <%=product.Name%><br/>
<%}%>

... что приведет к HTML примерно так (обратите внимание на обозначение массива в именах):

<input name="products[0].Id" type="hidden" value="123">
<input name="products[0].Selected" type="checkbox">
Widget
<input name="products[1].Id" type="hidden" value="987">
<input name="products[1].Selected" type="checkbox">
Gadget

... и метод контроллера, который обрабатывает сообщение:

public ActionResult SelectProducts(IList<ProductSelection> products)
{
     ...
}

При связывании параметр products будет содержать два экземпляра ProductSelection.

Одно предостережение: я не использовал новую привязку по умолчанию для сложных объектов. Скорее я использую или NameValueDeserializer или CastleBind, оба из MvcContrib. Они оба ведут себя так. Я предполагаю, что привязка в бета-версии будет работать так же.

2 голосов
/ 21 октября 2008

За ответ Крейга ... это безопаснее. Есть причуды к публикации нескольких элементов формы с одинаковыми именами. Я бы добавил, что было бы разумно обернуть логику, которая делает «коллекцию» элементов управления похожей на WebForms. В веб-формах добавляется имя элемента управления контейнера и добавляется индекс. Например, в Repeater элементы формы внутри были бы названы (что-то вроде) RepeaterName_Element1, RepeaterName_Element2. Когда вы идете, чтобы получить элементы, вы должны использовать FindControl или что-то в этом роде.

0 голосов
/ 21 октября 2008

В зависимости от ваших данных, вы можете либо вывести «CheckboxList» (что более невозможно в более новых версиях) и использовать параметр string[], либо вы можете настроить несколько форм и просто изменить действие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...