ModelState.AddModelError - Как я могу добавить ошибку, которая не для свойства?

190

Я проверяю свою базу данных, Create(FooViewModel fvm){...}чтобы увидеть, существует ли fvm.prop1и fvm.prop2уже в этой комбинации; если это так, я хочу добавить ошибку в состояние модели, а затем вернуть весь вид. Я попытался:

public ActionResult Create(FooViewModel fvm){
    if (ThatComboAlreadyExists(fvm)) {
      ModelState.AddModelError("Model", "There is already one like that");
      return View(fvm);
    }
}

... но я не вижу ошибок в том месте Html.ValidationSummary, где я предполагаю, что они появятся. У меня есть подозрение, что «Модель» - не тот ключ, но я не смог ничего найти в Google.

Скотт Бейкер
источник

Ответы:

330

В конце концов я наткнулся на пример использования, которое искал - назначить ошибку для модели в целом, а не для одного из ее свойств, как вы обычно называете:

ModelState.AddModelError(string key, string errorMessage);

но используйте пустую строку для ключа:

ModelState.AddModelError(string.Empty, "There is something wrong with Foo.");

Сообщение об ошибке будет отображаться так, <%: Html.ValidationSummary() %>как вы ожидаете.

Скотт Бейкер
источник
23
Этот случай заставляет меня задуматься: почему нет такого метода, как ModelState.AddError(errorMessage)или ModelState.AddGlobalError(errorMessage)... было бы интуитивно понятно, и было бы проще узнать, как добавить сообщение об ошибке, не связанное со свойствами какой-либо модели.
Рубенс Мариуццо
@Rubens: Да, но вы можете легко добавить такой метод с помощью методов расширения.
Johnny5
2
Вы также можете отобразить ошибку, используя@Html.ValidationMessage(string.Empty)
Ben Foster
ключ - это свойство вашей модели, привязанное к представлению - в котором есть ошибка - просто для ясности.
niico
1
ValidationSummaryErrors(bool excludePropertyErrors)Перегрузка будет отображать все ошибки проверки , если ее аргумент является ложным или только неимущественные конкретным (ключ = «») ошибки , если ее аргумент верно.
Suncat2000
26

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

В качестве примера мы проверяем, используется ли уже электронная почта в БД, и добавляем ошибку в свойство Email в действии, поэтому, когда я возвращаю представление, они знают, что есть ошибка, и как ее отобразить с помощью

<%: Html.ValidationSummary(true)%>
<%: Html.ValidationMessageFor(model => model.Email) %>

и

ModelState.AddModelError("Email", Resources.EmailInUse);
VinnyG
источник
1
В моем случае это кажется нелогичным - я проверяю, существует ли конкретная комбинация col1 и col2 в базе данных, поэтому кажется неправильным иметь свойство IsDuplicateOfAnotherRow в моем ViewModel. Оказывается, вы можете добавить ошибку в вашу модель - смотрите мой ответ.
Скотт Бейкер
1
Есть ли способ получить строку «Email» для AddModelError без использования хрупкой литеральной строки? Как (m=>m.email).SomeMagicToString()?
Снексе
Я не думаю, что вы должны идти с волшебной струной ... не лучшее, но все же хорошее решение
VinnyG
4
nameofОператор приходит в C # 6.0 решает эту проблему магии проблема строки. msdn.microsoft.com/en-us/magazine/dn802602.aspx
Р. Дж. Катбертсон
3

Поместить свойство точки модели в строки мне помогло: ModelState.AddModelError("Item1.Month", "This is not a valid date");

Крис
источник
2
Это действительно показывает неверный месяц в вашем пользовательском интерфейсе, но это не решает исходную проблему.
Скотт Бейкер
2
Первоначальная проблема связана с непониманием того, что представляет собой «ключ» в методе. Это проливает некоторый свет на то, как функционирует «ключ», поэтому полезно знать, что ключ не обязательно должен быть просто именем свойства, но также может ссылаться на вложенные свойства или специальное значение String.Empty.
Triynko