Позвольте мне начать с описания моего приложения в пошаговом формате.
Сначала у меня есть модель, сгенерированная Entity Framework. В нем у меня есть следующие сущности:
http://www.codetunnel.com/EFEntities.jpg
Теперь, чтобы реализовать проверку сущности, я использую частичные классы и обрабатываю перехватчики OnChanging, которые предоставляет EF. Вот пример частичного класса PostComment
:
namespace CodeTunnel.Domain.Models
{
public partial class PostComment : IDataErrorInfo
{
private Dictionary _errors = new Dictionary();
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. Поскольку он не допускает значения NULL, попытка привязать к нему значение NULL вызывает исключение. MVC проглатывает это исключение и аннулирует модель должным образом. Сообщение создается везде, где возникает это исключение. Я не знаю, создано ли сообщение EF или MVC (я ' m угадывает 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" вводится в качестве значения для Author: "Значение 'test' недействительно.". С обязательными полями просто значение равно null, поэтому между одинарными кавычками нечего ставить.
Некоторые люди (, такие как этот парень ) предлагают просто установить свойство в вашей модели на допускающее значение NULL. . Это НЕ приемлемое решение. Одна из причин, почему нет, заключается в следующем:
Ошибка 3031: проблема с сопоставлением.
Некоторые люди (, такие как этот парень ) предлагают вам просто установить свойство как допускающее значение NULL в вашей модели. Это НЕ приемлемое решение. Одна из причин, почему нет, заключается в следующем:
Ошибка 3031: проблема с сопоставлением.
Некоторые люди ( вроде этого парня ) предлагают вам просто установить свойство в вашей модели как допускающее значение NULL. Это НЕ приемлемое решение. Одна из причин, почему нет, заключается в следующем:
Ошибка 3031: проблема при сопоставлении. фрагменты, начинающиеся на строке 313: столбец, не допускающий значения NULL PostComments Body in table PostComments сопоставляется с обнуляемым свойство entity.
Кроме того, установка значения NULL просто не будет работать с типами, не допускающими значения NULL, такими как int, а переключение int на int, допускающее значение NULL, - неприятный беспорядок, в который я даже не буду вдаваться.
Итог Я хочу обрабатывать эти исключения из EF самостоятельно или, по крайней мере, настраивать генерируемое им сообщение, но я не знаю, как это сделать. Я совершенно потерялся. Все, что я хочу сделать, это настроить сообщение о том, что я считал очень простой проверкой модели!