Вопрос

VS 2010 Бета-версия 2, .NET 4.

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

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();

Свойство называется "Text" и имеет тип "text NOT NULL" в MS SQL 2008.

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

Это было полезно?

Решение

Привязываетесь ли вы непосредственно к объекту?Конечно, похоже на то.Итак, у вас есть два варианта:

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

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

Другие советы

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

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

Проверка на стороне сервера ТРЕБУЕМОГО строкового свойства в MVC2 Entity Framework 4 не работает

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

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

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

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

Похоже, что привязка к 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, показывая сообщение об ошибке при проверке и не приведет к сбою на сервере с Null.

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

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

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

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

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

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

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

У меня отлично работает!

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top