Сохраняющееся состояние HTML.CheckBox после POST – обновить ModelState?

У меня есть форма, состоящая из многих элементов (например, заказ товаров на заказ Amazon). Каждая строка имеет связанный с ними флажок, поэтому пользователь может выбрать несколько элементов и нажать «удалить».

Форма построена примерно так;

<% for (int i = 0; i < Model.OrderItems.Count; i++) { %> 
<tr>
    <td><%= Html.Hidden(String.Format("OrderItems[{0}].Id", i), Model.OrderItems[i].Id)%>
        <%= Html.CheckBox(String.Format("OrderItems[{0}].Checked", i), Model.OrderItems[i].Checked)%></td>
    <td><%= Html.TextBox(String.Format("OrderItems[{0}].Name", i), Model.OrderItems[i].Name)%></td>
    <td><%= Html.TextBox(String.Format("OrderItems[{0}].Cost", i), Model.OrderItems[i].Cost)%></td>
    <td><%= Html.TextBox(String.Format("OrderItems[{0}].Quantity", i), Model.OrderItems[i].Quantity)%></td>
</tr>       
<% } %>

Связыватель модели отлично справляется со своей задачей, и список заполняется правильно. Однако после того, как я обработаю запрос в действии (например, удалю соответствующие элементы) и верну новое представление, содержащее меньше элементов, состояние формы будет "полу-сохраненным". Некоторые флажки остаются отмеченными, даже если в модели редактирования для всех логических значений установлено значение false.

У меня нет этой проблемы, если я возвращаю RedirectToActionResult, но использование этого в качестве решения кажется немного хакерским.

Я думаю, что мне нужно сбросить/обновить ModelState или что-то подобное, но я не уверен, какие условия искать, чтобы узнать, как это сделать.


person Kirschstein    schedule 16.11.2009    source источник


Ответы (3)


Если вы проверите отображаемый HTML, я думаю, вы найдете скрытый ввод с тем же именем, что и ваш флажок; так работает HTML.Checkbox. Это приводит к отправке массива значений.

Это может быть причиной вашей проблемы.

Доброта,

Дэн

person Daniel Elliott    schedule 16.11.2009
comment
Да, это я понимаю, но почему это состояние запоминается по разным запросам? - person Kirschstein; 16.11.2009

Я хотел бы увидеть код вашего контроллера, но думаю, что вы viewModel заполняетесь по соглашению.

Я предполагаю, что в вашем действии Index вы создаете новую модель представления. Попробуйте назвать это по-другому, скажем, вызовите экземпляр indexViewModel, и он не будет автоматически собирать предыдущие данные viewModel.

person dove    schedule 30.03.2010

Ваша догадка, вероятно, верна, вам, вероятно, нужно позвонить

ModelState.Remove("OrderItems[{0}].Checked");

Кстати, использование Redirect обычно не считается взломом, на самом деле это довольно хорошая практика, называемая Post Redirect Get (PRG).

person Betty    schedule 23.10.2012