ASP.Net MVC ModelState / Html.TextBox проблема обратной передачи - PullRequest
5 голосов
/ 07 мая 2009

У меня возникла проблема в форме, которую я пытаюсь опубликовать. В сценарии, где форма не проверяется, я беру стандартный маршрут вызова ModelState.AddModelError(), а затем возвращаю результат просмотра.

Дело в том, что помощники HTML. * Должны извлекать опубликованное значение при рендеринге, и я замечаю, что мои текстовые поля ТОЛЬКО делают это, если я включаю их в список параметров действия обратной передачи, который не должен не требуется, поскольку в некоторых формах слишком много полей, чтобы перечислить их все в качестве параметров.

Мой код действия примерно:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name)
{
    var dataDefinition = ...

    // do some validation stuff
    if (!ModelState.IsValid)
    {
        // manually set checkbox fields via ViewData seeing as this STILL doesn't work in MC 1.0 :P
        // ...
        return View(dataDefinition);
    }

}

Теперь dataDefinition (который является сущностью LINQ to SQL) имеет поле MinVolume , которое обрабатывается в представлении этой строкой:

Minimum: <%= Html.TextBox("MinVolume", null, new { size = 5 })%>

Тем не менее, когда представление отображается после неудачной проверки ModelState, значение, введенное в него на исходной странице, которую мы разместили, не сохраняется, ЕСЛИ Я не включил его в качестве параметра в метод обратной передачи. Буквально я могу «решить проблему», выполнив это:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name, string minVolume)

По какой-то причине это заставит значение поля быть сохраненным. Это кажется мне глупым, потому что моя форма имеет гораздо больше значений, чем просто это, и мне не нужно было добавлять параметр только для этого поля.

Есть идеи?

Ответы [ 6 ]

6 голосов
/ 14 мая 2009

О, боже, я только что улучшил дизайн своего приложения. Проблема возникает, потому что у вас есть пользовательская проверка (у меня тоже). Вы должны добавить после

ModelState.AddModelError()

это

ModelState.SetModelValue("MinVolume", ValueProvider["MinVolume"]);

Это должно быть

Mimum:<%=Html.Textbox("MinVolume")%>

Все еще не уверен, почему это работает, но у меня это сработало.

4 голосов
/ 09 мая 2009

Может быть, ваш код:

<%= Html.TextBox("MinVolume", null, new { size = 5 })%>

.. имеет null для параметра по умолчанию? Возможно, если вы измените значение null на Model.MinVolume, оно сохранит значение. Как это:

<%= Html.TextBox("MinVolume", Model.MinVolume, new { size = 5 })%>

Я не уверен, что ваше действие возвращает значение MinVolume в модели tho. Если это произойдет, вышеупомянутое должно работать. Иначе вам может понадобиться немного изменить рефакторинг.

3 голосов
/ 07 мая 2009

Какой ключ вы используете при установке значения в ModelState при ошибке? Код, который устанавливает параметр значения для TextBox, выглядит следующим образом:

Соответствующая часть загруженного фреймворка с кодом .

string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);

Как вы можете видеть, существует ли значение попытки, оно будет использовать его, но только если доступен тот же ключ.

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

РЕДАКТИРОВАТЬ : Для того чтобы значения были сохранены, их необходимо каким-то образом связать с моделью. Один из способов сделать это - добавить их в список параметров. Другой способ - использовать UpdateModel (с именами параметров в белом списке или без белого). Третий способ - добавить параметр явно в модель, как в ответе @ Jenea. Поскольку помощник извлекает только из состояния модели, они должны быть там, чтобы значения были сохранены. Он не смотрит на свойство формы запроса.

0 голосов
/ 07 октября 2009

Обратитесь к этой статье, чтобы увидеть различные способы обработки обратной передачи в ASP.NET MVC

текст ссылки

0 голосов
/ 14 мая 2009

Другое решение, если вы наберете в виду:

<%var minVolume=Request["MinVolume"]??"";%>
<%=Html.Textbox("MinVolume",minVolume,new {size=5})%>
0 голосов
/ 13 мая 2009

Как я понимаю, решение таково:

[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(int id, FormCollection form)
{
    T itemToUpdate = repository.Get(id);
    UpdateModel(itemToUpdate, form.ToValueProvider());

    if (itemToUpdate.IsValid())
    {
        repository.SaveOrUpdate(itemToUpdate);
        return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
    }

    repository.DbContext.RollbackTransaction();
    return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
}

удачи!

...