2009-05-07 3 views
5

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

Дело в том, что 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 к SQL сущности) имеет поле MinVolume, обрабатывается в представлении этой линии:

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

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

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

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

Любые идеи?

ответ

4

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

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

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

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

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

+0

Нет, указав нуль, предполагается, что для запроса значения должен использоваться существующий контекст модели. Задание MinVolume является явным и заставит использовать это значение вместо того, что было ранее представлено. –

+0

Неверный. Задание MinVolume просматривает ViewDataDoctionary, а затем ModelStateDictionary для последующих сообщений. Поэтому, если Model.MinVolume говорит, что 5 из-за редактирования, то указание MinVolume поместит 5 в TextBox. Затем, если сообщение сделано (скажем, значение 3), но найдено недействительным, TextBox покажет 3 второй раз. Ты это пробовал? Обычно вы указываете null в представлении «Создать» или «Создать», чтобы исходная запись отображалась пустой в поле, а последующие сообщения сохраняли введенное значение. –

+0

Это именно то, как я это делаю и каждый раз работаю. Я нигде не видел, что вам нужно указать null. Ссылка на то, где вы это видели, была бы хорошей. – sirrocco

3

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

Соответствующая часть downloaded framework code.

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

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

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

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

+0

Это поле не проверяется вообще - на данном этапе не обязательно. Следовательно, это просто «невинный наблюдатель» в форме и ожидает, что его новое значение сохранится, если одно из других полей не будет себя вести и, таким образом, заставляет форму делать второй раз. –

+0

Мне интересно, если я ошибочно сделаю предположение, что ModelState должен пытаться сохранить все поля с именами, которые соответствуют модели. Возможно, он сохраняет только поля, которые передаются через список параметров или ссылаются через AddModelError? Если это так, кажется, это глупое видение, поскольку я хочу сохранить все в форме, а не только в конкретных случаях. С другой стороны, MVC по-прежнему не сохраняет поля флажков должным образом ... –

0

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

[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())); 
} 

удачи!

6

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

ModelState.AddModelError() 

это

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

Учитывая это должно быть

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

До сих пор не знаю, почему это работает, но это работает для меня.

+0

oooh ... это может быть ответ! будет проверять утром, когда я приступаю к работе. Благодарю. –

+2

Он работает, потому что он добавляет значение модели, из которой помощник вытягивает значения. Использование UpdateModel также будет работать, и я использую то, что я использую, и почему мои значения текстового поля сохраняются. – tvanfosson

0

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

<%var minVolume=Request["MinVolume"]??"";%> 
<%=Html.Textbox("MinVolume",minVolume,new {size=5})%> 
0

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

link text

+0

Хорошая статья для стартера. – 2009-10-06 21:58:17