ASP.Net Проблема с обратной отправкой MVC ModelState / Html.TextBox

StackOverflow https://stackoverflow.com/questions/834842

  •  08-07-2019
  •  | 
  •  

Вопрос

У меня возникла проблема с формой, которую я пытаюсь опубликовать.В сценарии, когда форма не проходит проверку, я использую стандартный маршрут вызова 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) имеет поле Минимальный объем, обрабатывается в представлении этой строкой:

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

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

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

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

Есть какие-нибудь идеи?

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

ModelState.AddModelError()

это

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

С учетом того, что это должно быть

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

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

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

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

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

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

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

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

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

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

удачи!

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

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

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

текст ссылки

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top