Ответ 1
Помощник сначала будет искать значения POSTED и использовать их. Когда вы отправляете форму, она забирает старое значение идентификатора. Ваше обходное решение верное.
Что-то довольно странное происходит с моим приложением:
У меня есть следующее свойство в моей модели ViewModel:
public int? StakeholderId { get; set; }
Он отображается в частичном виде следующим образом:
<%= Html.Hidden("StakeholderId", Model.StakeholderId) %>
Форма отправляется, и соответствующее действие контроллера генерирует идентификатор и обновляет модель перед возвратом того же представления с обновленной моделью
Проблема, с которой я сталкиваюсь, заключается в том, что скрытое поле не имеет ничего в своем атрибуте "value", которое отображается во второй раз, даже если значение StakeholderId теперь имеет значение.
Если я просто вывожу значение самостоятельно, оно отображается на странице, поэтому я получил его для отображения значения, выполнив следующее:
<input type="hidden" id="StakeholderId" name="stakeholderId" value="<%: Model.StakeholderId %>" />
Но довольно странно, что помощник не поднимает обновленное значение?
(Я использую jQuery для отправки форм и рендеринга результатов действий в divs, но я проверил, и html, который я возвращаю, уже ошибочен, прежде чем jQuery что-то делает с этим, поэтому я не думаю, что это много делать что-либо)
UPDATE
С тех пор я обнаружил, что я также могу очистить соответствующий ключ ModelState до того, как действие моего контроллера вернет частичный вид.
Помощник сначала будет искать значения POSTED и использовать их. Когда вы отправляете форму, она забирает старое значение идентификатора. Ваше обходное решение верное.
Как дополнение к этой проблеме, нужно быть очень осторожным с несколькими формами на одной странице, например, в сетке, скажем, сгенерированной с использованием Ajax.BeginForm.
У вас может возникнуть соблазн написать что-то по строкам:
@foreach (var username in Model.TutorUserNames)
{
<tr>
<td>
@Html.ActionLink(username, MVC.Admin.TutorEditor.Details(username))
</td>
<td>
@using (Ajax.BeginForm("DeleteTutor", "Members",
new AjaxOptions
{
UpdateTargetId = "AdminBlock",
OnBegin = "isValidPleaseWait",
LoadingElementId = "PleaseWait"
},
new { name = "DeleteTutorForm", id = "DeleteTutorForm" }))
{
<input type="submit" value="Delete" />
@Html.Hidden("TutorName", username)
}
</td>
</tr>
}
Летальная линия здесь:
@Html.Hidden("TutorName", username)
... и намерены использовать TutorName в качестве параметра действия. EG:
public virtual ActionResult DeleteTutor(string TutorName){...}
Если вы это сделаете, неприятный сюрприз, в котором вы участвуете, заключается в том, что Html.Hidden( "TutorName", имя пользователя), как объясняет Дарин Димитров, отображает последнее значение POSTED. То есть, независимо от вашего цикла, ВСЕ элементы будут отображаться с TutorName последнего удалённого Tutor!
Слово вокруг, в синтаксисе Razor, должно заменить вызов @Html.Hidden явным входным тегом:
<input type="hidden" id="TutorName" name="TutorName" value='@username' />
Это работает как ожидалось.
Т.е:
НИКОГДА, НИКОГДА НЕ ИСПОЛЬЗУЙТЕ Html.Hidden ДЛЯ ПРОСМОТРА ПАРАМЕТРА ВЕРНУТЬСЯ К ВАШИМ ДЕЙСТВИЯМ, КОГДА ВЫ ИСПОЛЬЗУЕТЕ МНОЖЕСТВЕННЫЕ ФОРМЫ В СЕТЕВОЙ СЕТИ!!!
При построении скрытого входного тега вам нужно указать имя и идентификатор, установить одинаковое значение, иначе на момент написания статьи (февраль 2011 г.) это будет работать неправильно. Конечно, не в Google Chrome. Все, что вы получаете, это возврат нулевого параметра, если у вас есть только идентификатор и атрибут имени.