Обработка обязательных полей в ASP.NET MVC при использовании Entity Framework

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

сначала у меня есть модель, сгенерированная 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

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

в причина, по которой вы не можете настроить сообщение об ошибке, отображаемое для обязательных полей, заключается в том, что свойство model не имеет значения null. Поскольку он не nullable, попытка привязать к нему значение null вызывает исключение. В MVC ласточки это excepion и доверие модели как надо. Сообщение генерируется везде, где происходит это исключение. Я не знаю, генерируется ли сообщение EF или MVC (я предполагаю, что MVC, поскольку он отвечал за проглатывание исключения в первую очередь). Я не знаю как настроить это сообщение. Как вы можете видеть, он всегда говорит, что "значение" недопустимо."что, я полагаю, не совсем ужасно, но на самом деле не очень удобно.

он попадает в валидатор моего имени и проверяет, является ли ваше имя "fred" просто прекрасным, потому что не возникает никаких исключений. Что касается EF, переданное значение в порядке. Это не так, пока он не доберется до моего OnAuthorChanging метод, который он понимает, что это не хорошо. Это правильное поведение и работает просто отлично.

если я брошу исключение в моих событиях OnChanging вместо добавления в my 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 " недопустимо.". С требуемыми полями просто значение равно null, поэтому между одинарными кавычками нечего ставить.

несколько человек (такой Гай!--12-->) предложите вам просто установить свойство nullable в вашей модели. Это неприемлемое решение. Одна из причин, почему нет, такова:

ошибка 3031: проблема в сопоставлении фрагменты, начинающиеся на линии 313:необнуляемый столбец Посткомменты.Тело в таблице PostComments сопоставляется с nullable свойство сущности.

кроме того, установка nullable просто не будет работать на ненулевых типах, таких как int, а переключение int на nullable int-это Гадкий бардак, в который я даже не хочу попасть.

суть в том, что я хочу обрабатывать эти исключения из EF сам или, по крайней мере, настроить сообщение, которое он генерирует, но я не знаю, как. Я совсем запутался. Все, что я хочу сделать, это настроить сообщение о том, что я считал очень простой проверкой модели!

любая помощь очень ценится.

2 ответов


MVC-это проверка модели на основе типа не nullible, как вы обнаружили. Это добавление ошибок в ModelState перед запуском пользовательской проверки.

у меня было это раньше, и я обошел его, пройдя через Modelstate в начале действия и удалив все, а затем выполнив свою пользовательскую проверку (плохо!!)

затем найдено, даже если вы не используете аннотации данных в качестве основной формы проверки, вы можете настроить сообщение, которое добавление [обязательно к типу non nullible в классе buddy и указание сообщения.

Это что-то вроде этого:

[MetadataType(typeof(YourClassMetadata))]
public partial class YourClass
{       
  //buddyclass to entity class
  class YourClassMetadata 
  {
    [Required(ErrorMessage="Your custom overriding error message")]
    public int NonNullablePropertyThatIsGivingYouProblems {get;set;}
  }
}

Я начал смотреть на fluent validation (http://fluentvalidation.codeplex.com) для mvc, и они, похоже, отключают проблему в глобальном масштабе.asax, в on application_start (), добавив строку

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

но я могу ошибаться на этот счет.


Я знаю, что это не совсем то, что вы спросили, но я только что закончил проект на прошлой неделе, в котором я использовал проверку на стороне клиента MVC 3 с аннотациями данных и ненавязчивым javascript. Его довольно полный рот, но работает замечательно. Вы можете настроить regex, maxlenght, required и все другие атрибуты, и он проверяет все это на клиенте. Это делает проверку формы намного быстрее для пользователя.

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

надеюсь, что это помогает,