Ошибка Entity Framework при отправке пустых полей

VS 2010 Beta 2, .NET 4.

В моем приложении ASP.NET MVC 2, когда я отправляю форму в метод действия, который принимает объект, созданный структурой сущностей, я получаю следующую ошибку:

Exception Details: System.Data.ConstraintException: This property cannot be set to a  
null value.

Source Error: 


Line 4500:                OnTextChanging(value);
Line 4501:                ReportPropertyChanging("Text");
Line 4502:                _Text = StructuralObject.SetValidValue(value, false);
Line 4503:                ReportPropertyChanged("Text");
Line 4504:                OnTextChanged();

Свойство называется "Текст" и имеет тип "текст НЕ ПУСТО" в MS SQL 2008.

Мое действие проверит, является ли значение nullorempty, если это так, будет добавлена ​​ошибка модели, но я получаю ошибку, как только я отправляю форму.

8 ответов

Решение

Связываете ли вы непосредственно с сущностью? Конечно, похоже на это. Итак, у вас есть два варианта:

  1. Напишите пользовательский связыватель модели, который переводит нуль -> пустую строку.
  2. Привязать к редактируемой модели, которая вместо этого допускает пустые значения, а затем изменить ее на пустую строку при копировании значений в сущность в действии.

Я бы выбрал № 2 лично. Я думаю, что вы всегда должны использовать модели просмотра / редактирования, и это отличный пример того, почему.

У меня была такая же проблема. Я оглянулся вокруг и нашел здесь работу. Это описывает проблему как вызванную проверкой EF, имеющей место перед проверкой обязательного поля. Это также показывает, как мы можем обойти эту проблему, используя [DisplayFormat] Тег. Надеюсь, что это поможет вам.

Вот ссылка на вопрос и обходной путь:

Проверка на стороне сервера НЕОБХОДИМОГО свойства строки в MVC2 Entity Framework 4 не работает

У меня была такая же проблема, и я решил ее false в true как это:

Line 4502:
_Text = StructuralObject.SetValidValue(value, false);

Это проблема с MVC2 и Entity Framework 4 или это задумано? Похоже, что проверка свойств EF работает нормально для полей типа datetime (не обязательных) (обязательных), а проверка типов данных числовых и строковых полей работает без необходимости использования ViewModels.

Я воссоздал проблему, используя простую таблицу FOOBAR, используя единственный столбец varchar(50), не имеющий значения null, называемый barName, в slq 2008. Я сгенерировал модель EF из этой базы данных и быстро добавил контроллер и представление CREATE для сущности FOOBAR. Если я пытаюсь POST выполнить действие CREATE, не вводя значение для свойства barName, VS переходит в исключение в файле designer.cs модели (как и в предыдущем примере). Когда я пытаюсь пройти мимо исключения, в форме появляется сообщение проверки, и поле выделяется розовым цветом.

Кажется, что-то идет не в правильной последовательности. Потому что исключение происходит до того, как VS перейдет в метод HTTPPOST CREATE.

Я нашел код из примера ASP.Net MvcMusicStore полезным. http://mvcmusicstore.codeplex.com/releases/view/44445

Похоже, что привязка к ViewModel устраняет проблему.

namespace MvcMusicStore.ViewModels
{
    public class StoreManagerViewModel
    {
        public Album Album { get; set; }
        public List<Artist> Artists { get; set; }
        public List<Genre> Genres { get; set; }
    }
}
........

namespace MvcMusicStore.Models
{
    [MetadataType(typeof(AlbumMetaData))]
    public partial class Album
    {
        // Validation rules for the Album class

        [Bind(Exclude = "AlbumId")]
        public class AlbumMetaData
        {
            [ScaffoldColumn(false)]
            public object AlbumId { get; set; }

            [DisplayName("Genre")]
            public object GenreId { get; set; }

            [DisplayName("Artist")]
            public object ArtistId { get; set; }

            [Required(ErrorMessage = "An Album Title is required")]
            [StringLength(160)]
            public object Title { get; set; }

            [DisplayName("Album Art URL")]
            [StringLength(1024)]
            public object AlbumArtUrl { get; set; }

            [Required(ErrorMessage = "Price is required")]
            [Range(0.01, 100.00, ErrorMessage="Price must be between 0.01 and 100.00")]
            public object Price { get; set; }
        }
    }
}

Ответ Ашиша Шакьи мне помог. Я добавил этот атрибут в свойство, и теперь он работает.

[DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")]

Так это выглядит так:

    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    [DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")]
    public global::System.String MyProperty
    {
        get
        {
            return _MyProperty;
        }
        set
        {
            OnMyPropertyChanging(value);
            ReportPropertyChanging("MyProperty");
            _MyProperty = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("MyProperty");
            OnMyPropertyChanged();
        }
    }

Импортируйте пространство имен:

using System.ComponentModel.DataAnnotations;

И добавить свойство атрибута [Required]

[Required]
public global::System.String MyProperty
    {
        get
        {
            return _MyProperty;
        }
        set
        {
            OnMyPropertyChanging(value);
            ReportPropertyChanging("MyProperty");
            _MyProperty = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("MyProperty");
            OnMyPropertyChanged();
        }
    }

Таким образом, ModelState.IsValid равно false, показывает сообщение об ошибке при проверке и не завершится ошибкой на сервере с нулевым значением.

Я установил свойство StoreGeneratedPattern как вычисляемое для каждого поля, и это решило проблему для меня.

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

Svavar и HackITMngr были на правильном пути, однако объединение обоих дает лучший результат. Вы не хотите украшать сгенерированные классы, так как рискуете потерять свои пользовательские изменения при модификации модели EF.

[MetadataType (typeof (MyTableMetaData))] публичный частичный класс MyTable { // Правила проверки для класса Album

    public class MyTableMetaData
    {
        [DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")]
        public string MyTextProperty { get; set; }
    }
}

Чтобы уладить любые споры между двумя. Я бы сказал, что Svavar был прямым ответом, HackITMngr был улучшением.

Прекрасно работает для меня!

Другие вопросы по тегам