Может ли кто-нибудь дать мне краткое определение роли ModelState в Asp.net MVC (или ссылку на один). В частности, мне нужно знать, в каких ситуациях нужно или желательно звонить ModelState.Clear()
.
Немного открытый, да ... извините, я думаю, это может помочь, если я расскажу вам, что я на самом деле делаю:
У меня есть действие редактирования на контроллере под названием «Страница». Когда я впервые вижу форму для изменения деталей страницы, все загружается нормально (привязка к объекту «MyCmsPage»). Затем я нажимаю кнопку, которая генерирует значение для одного из полей объекта MyCmsPage ( MyCmsPage.SeoTitle
). Он генерирует отлично и обновляет объект, а затем я возвращаю результат действия с недавно измененным объектом страницы и ожидаю, что соответствующее текстовое поле (визуализированное с помощью <%= Html.TextBox("seoTitle", page.SeoTitle)%>
) будет обновлено ... но, увы, оно отображает значение из старой загруженной модели.
Я работал над этим, используя, ModelState.Clear()
но мне нужно знать, почему / как это сработало, поэтому я не делаю это вслепую.
PageController:
[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
// add the seoTitle to the current page object
page.GenerateSeoTitle();
// why must I do this?
ModelState.Clear();
// return the modified page object
return View(page);
}
Aspx:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
<div class="c">
<label for="seoTitle">
Seo Title</label>
<%= Html.TextBox("seoTitle", page.SeoTitle)%>
<input type="submit" value="Generate Seo Title" name="submitButton" />
</div>
источник
Ответы:
Думаю, это ошибка в MVC. Сегодня я часами боролся с этой проблемой.
Учитывая это:
Вид отображается с исходной моделью без учета изменений. Я подумал, может быть, мне не нравится использовать ту же модель, поэтому я попробовал вот так:
И все же вид отображается с оригинальной моделью. Что странно, когда я помещаю точку останова в представление и исследую модель, она меняет значение. Но поток ответов имеет старые значения.
В конце концов я обнаружил ту же работу, что и вы:
Работает как положено.
Я не думаю, что это «особенность», не так ли?
источник
Обновить:
View()
из действия POST. Вместо этого используйте PRG и перенаправьте на GET, если действие выполнено успешно.View()
из действия в POST, сделайте это для проверки формы, и сделать это так , как MVC разработан с использованием встроенного в помощниках. Если вы сделаете это таким образом, вам не нужно использовать.Clear()
ModelState
поскольку вам все равно не следует его использовать.Старый ответ:
ModelState в MVC используется в первую очередь для описания состояния объекта модели в значительной степени в зависимости от того, является ли этот объект действительным или нет. Этот урок должен многое объяснить.
Как правило, вам не нужно очищать ModelState, поскольку он поддерживается механизмом MVC для вас. Очистка вручную может привести к нежелательным результатам при попытке придерживаться передовых методов проверки MVC.
Похоже, вы пытаетесь установить для заголовка значение по умолчанию. Это должно быть сделано, когда объект модели создается (уровень домена где-то или в самом объекте - ctor без параметров), в действии get, чтобы он спускался на страницу в первый раз или полностью на клиенте (через ajax или что-то еще) так что он выглядит так, как если бы пользователь ввел его, и он возвращается с коллекцией опубликованных форм. Некоторым образом ваш подход к добавлению этого значения при получении коллекции форм (в действии POST // Edit) вызывает такое странное поведение, которое может привести к
.Clear()
появлению работающего на вас. Поверьте мне - вы не хотите использовать клир. Попробуйте одну из других идей.источник
Если вы хотите очистить значение для отдельного поля, я нашел полезным следующий прием.
Примечание. Замените «Ключ» на имя поля, которое вы хотите сбросить.
источник
Ну, ModelState в основном содержит текущее состояние модели с точки зрения проверки,
ModelErrorCollection: представляют ошибки, когда модель пытается привязать значения. ех.
или как параметр в ActionResult
ValueProviderResult : сохраните сведения о попытке привязки к модели. ех. AttemptedValue, Культура, RawValue .
Метод Clear () следует использовать с осторожностью, поскольку он может привести к неожиданным результатам. И вы потеряете некоторые приятные свойства ModelState, такие как AttemptedValue, это используется MVC в фоновом режиме для повторного заполнения значений формы в случае ошибки.
источник
У меня был случай, когда я хотел обновить модель принятой формы и не хотел «перенаправлять на действие» по причине производительности. Предыдущие значения скрытых полей сохранялись в моей обновленной модели, что приводило к множеству проблем !.
Несколько строк кода вскоре идентифицировали элементы в ModelState, которые я хотел удалить (после проверки), поэтому новые значения были использованы в форме: -
источник
Что ж, похоже, многих из нас это укусило, и хотя причина, по которой это происходит, имеет смысл, мне нужен был способ убедиться, что значение моей модели было показано, а не ModelState.
Некоторые предлагали
ModelState.Remove(string key)
, но не совсем понятно, чтоkey
должно быть, особенно для вложенных моделей. Вот несколько методов, которые я придумал, чтобы помочь в этом.RemoveStateFor
Метод будет приниматьModelStateDictionary
, модель, и выражение для искомой собственности, и удалить его.HiddenForModel
может использоваться в вашем представлении для создания скрытого поля ввода, используя только значение из модели, сначала удалив его запись ModelState. (Это можно легко расширить для других вспомогательных методов расширения).Вызов из контроллера выглядит так:
или с такой точки зрения:
Он используется
System.Web.Mvc.ExpressionHelper
для получения имени свойства ModelState.источник
Я хотел обновить или сбросить значение, если оно не подтвердилось, и столкнулся с этой проблемой.
Простой ответ, ModelState.Remove, ... проблематичен ... потому что, если вы используете помощники, вы действительно не знаете имени (если вы не придерживаетесь соглашения об именах). Если, возможно, вы не создадите функцию, которую и ваш пользовательский помощник, и ваш контроллер могут использовать для получения имени.
Эта функция должна была быть реализована в качестве опции для помощника, где по умолчанию этого не происходит, но если вы хотите, чтобы непринятый ввод отображался повторно, вы можете просто сказать об этом.
Но, по крайней мере, теперь я понимаю суть вопроса;).
источник
Remove()
выбрать правильный ключ.Получил в конце концов. Мой Custom ModelBinder, который не был зарегистрирован, делает следующее:
Значит, проблема была вызвана чем-то, что делала привязка модели по умолчанию. Не уверен, что, но моя проблема, по крайней мере, решена теперь, когда моя привязка пользовательской модели регистрируется.
источник
Обычно, когда вы обнаруживаете, что боретесь со стандартными практиками фреймворка, пора пересмотреть свой подход. В этом случае поведение ModelState. Например, если вам не нужно состояние модели после POST, подумайте о перенаправлении на get.
ИЗМЕНИТЬ, чтобы ответить на комментарий культуры:
Вот что я использую для работы с многокультурным приложением MVC. Сначала подклассы обработчика маршрута:
А вот как я подключаю маршруты. После создания маршрутов я добавляю свой субагент (example.com/subagent1, example.com/subagent2 и т. Д.), А затем код культуры. Если все, что вам нужно, это культура, просто удалите субагент из обработчиков маршрутов и маршрутов.
источник
Что ж, похоже, это сработало на моей странице Razor, и даже не выполняло обхода к файлу .cs. Это старый способ HTML. Может быть полезно.
источник