Хорошо, эта проблема действительно у меня под кожей.Позвольте мне начать с описания моего приложения в пошаговом формате.
Сначала у меня есть модель, созданная в Entity Framework.В нем есть следующие сущности:
http://www.codetunnel.com/EFEntities.jpg
Теперь, чтобы реализовать проверку сущности, я использую частичные классы и обрабатываю хуки OnChanging, которые предоставляет EF.Вот пример частичного класса PostComment
:
namespace CodeTunnel.Domain.Models
{
public partial class PostComment : IDataErrorInfo
{
private Dictionary<string, string> _errors = new Dictionary<string, string>();
partial void OnAuthorChanging(string value)
{
//Validating anything but required value works fine.
//Like this pseudo-validator.
if (value.ToLower() != "fred")
_errors.Add("Author", "Sorry, your name must be Fred.");
}
partial void OnBodyChanging(string value)
{
//Required value validation does not work, I will tell you why below.
if (string.IsNullOrEmpty(value))
_errors.Add("Body", "Body is required.");
}
#region -= IDataErrorInfo methods =-
public string Error
{
get { return string.Empty; }
}
public string this[string columnName]
{
get
{
if (_errors.ContainsKey(columnName))
return _errors[columnName];
return string.Empty;
}
}
#endregion
}
}
Обратите внимание, что мой класс наследуется от IDataErrorInfo
.MVC проверяет это на наличие ошибок проверки по умолчанию.Если он находит что-либо, он делает недействительной модель и использует сохраненные ошибки в качестве сообщений для помощников проверки в представлении.Я почти уверен, что когда EF выдает исключение, этот словарь даже не заполняется значением этого свойства.На самом деле, я даже не уверен, что MVC заходит так далеко, что ищет значение после обнаружения и аннулирования модели после сгенерированного EF исключения.
Вот снимок экрана проблемы, включая примерпсевдо-валидатор, чтобы вы могли видеть, что он работает:
http://www.codetunnel.com/ValidationError.jpg
Как видите, сообщение об ошибке не появилось.Тем не менее, он правильно подтвердил поле как недействительное.Если я добавлю туда значение, то это будет хорошо.Я провел МНОГИЕ исследования по этой проблеме, и вот что я знаю:
Причина, по которой вы не можете настроить сообщение об ошибке, отображаемое для обязательных полей, заключается в том, что свойство модели не имеет значения NULL.Поскольку он не может быть обнуляемым, попытка связать с ним нулевое значение вызывает исключение.MVC проглатывает это исключение и делает модель недействительной, как следует.Сообщение генерируется везде, где возникает это исключение.Я не знаю, генерируется ли сообщение EF или MVC (я предполагаю, что MVC, так как он был ответственен за проглатывание исключения в первую очередь).Я не знаю, как настроить это сообщение.Как вы можете видеть, он всегда говорит: «Значение» недопустимо ».что, я полагаю, не совсем ужасно, но на самом деле это не очень удобно для пользователя.
Он попадает в мой валидатор имени и проверяет, хорошо ли ваше имя "fred", потому что исключение не выдается.Что касается EF, то переданное значение в порядке.Только когда он доходит до моего OnAuthorChanging
метода, он понимает, что это не хорошо.Это правильное поведение и работает отлично.
Если я добавлю исключение в мои события OnChanging вместо добавления в свой словарь IDataErrorInfo
, я могу создать такое же сообщение проверки, только оно помещает введенное значение междуодинарные кавычки.Пример:
partial void OnAuthorChanging(string value)
{
if (value.ToLower() != "fred")
//_errors.Add("Author", "Sorry, your name must be Fred.");
throw new Exception("Sorry, your name must be Fred.");
}
Этот код показывает это сообщение, когда в качестве значения для Автора вводится «test»: «Значение« test »недопустимо.».С обязательными полями просто значение равно нулю, поэтому между одинарными кавычками нечего ставить.
Несколько человек ( как этот парень ) предлагают просто установить для свойства значение nullableв твоей модели.Это НЕ приемлемое решение.Одна из причин, по которой это не так:
Ошибка 3031: проблема в отображении фрагментов, начинающихся со строки 313. Ненулевой столбец PostComments.Body в таблице PostComments сопоставляется со свойством объекта, допускающим значение NULL.
Кроме того, установка nullable просто не будет работать с необнуляемыми типами, такими как int, а переключение int на nullable int - отвратительный беспорядок, в который я даже не попаду.
Суть в том, что я хочу обработать эти исключения из EF самостоятельно или, по крайней мере, настроить сообщение, которое оно генерирует, но я не знаю как.Я полностью потерян.Все, что я хочу сделать, это настроить сообщение о том, что я считал очень простой проверкой модели!
Любая помощь очень ценится.