Asp.net MVC ModelState. Ясный

Журнал доктора Dobbs является журналом довольно хорошего всеобъемлющего программиста. Покрытия весь способ материала.

114
задан Matt Kocaj 15 August 2016 в 06:56
поделиться

5 ответов

Я думаю, что это ошибка в MVC. Сегодня я часами боролся с этой проблемой.

Учитывая это:

public ViewResult SomeAction(SomeModel model) 
{
    model.SomeString = "some value";
    return View(model); 
}

Вид визуализируется с использованием исходной модели без учета изменений. Так что я подумал, может быть, мне не нравится, что я использую ту же модель, поэтому я попробовал вот так:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    return View(newModel); 
}

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

В конце концов я обнаружил ту же работу, что и вы:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    ModelState.Clear();
    return View(newModel); 
}

Работает, как ожидалось.

Я не думаю, что это "особенность", не так ли?

134
ответ дан 24 November 2019 в 02:34
поделиться

Ну, ModelState в основном содержит текущее состояние модели с точки зрения проверки, оно содержит

ModelErrorCollection: Представляет ошибки, когда модель пытается связать значения. напр.

TryUpdateModel();
UpdateModel();

или аналогичный параметр в ActionResult

public ActionResult Create(Person person)

ValueProviderResult : содержит сведения о предпринятом связывании с моделью. напр. AttemptedValue, Culture, RawValue .

Метод Clear () следует использовать с осторожностью, поскольку он может привести к неожиданным результатам. И вы потеряете некоторые приятные свойства ModelState, такие как AttemptedValue, это используется MVC в фоновом режиме для повторного заполнения значений формы в случае ошибки.

ModelState["a"].Value.AttemptedValue
6
ответ дан 24 November 2019 в 02:34
поделиться

В конце концов, понял. Мой Custom ModelBinder, который не регистрировался и делает следующее:

var mymsPage = new MyCmsPage();

NameValueCollection frm = controllerContext.HttpContext.Request.Form;

myCmsPage.SeoTitle = (!String.IsNullOrEmpty(frm["seoTitle"])) ? frm["seoTitle"] : null;

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

0
ответ дан 24 November 2019 в 02:34
поделиться

Обновление:

  • Это не ошибка.
  • Прекратите возвращать View () из действия POST. Вместо этого используйте PRG и перенаправьте на GET, если действие выполнено успешно.
  • Если вы возвращаете View () из действия POST, выполните это для проверки формы, и делать это так, как MVC разработан с использованием встроенных помощников. Если вы сделаете это таким образом, вам не нужно использовать .Clear ()
  • . Если вы используете это действие для возврата ajax для SPA , используйте веб-контроллер api и забудьте о ModelState , так как вы все равно не должны его использовать.

Старый ответ:

ModelState в MVC используется в первую очередь для описания состояния объекта модели в основном в зависимости от того, является ли этот объект действительный или нет. Это руководство должно многое объяснить.

Как правило, вам не нужно очищать ModelState, так как оно поддерживается механизмом MVC для вас. Очистка вручную может привести к нежелательным результатам при попытке придерживаться лучших практик проверки MVC.

Похоже, вы пытаетесь установить значение по умолчанию для заголовка. Это должно быть сделано, когда объект модели создается (уровень домена где-то или в самом объекте - ctor без параметров), в действии get, чтобы он спускался на страницу в первый раз или полностью на клиенте (через ajax или что-то еще) так что он выглядит так, как если бы пользователь ввел его, и он возвращается с коллекцией опубликованных форм. Некоторым образом ваш подход к добавлению этого значения при получении коллекции форм (в действии POST // Edit) вызывает такое странное поведение, которое может привести к . Clear () появляется , чтобы работать на вас. Поверьте мне - вы не хотите использовать клир. Попробуйте одну из других идей.

42
ответ дан 24 November 2019 в 02:34
поделиться

Если вы хотите очистить значение для отдельного поля, я счел полезным следующий прием.

ModelState.SetModelValue("Key", new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture));

Примечание: Замените «Ключ» на имя поля, которое вы хотите сбросить.

17
ответ дан 24 November 2019 в 02:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: