代码之家  ›  专栏  ›  技术社区  ›  Omar

提交空字段时出现实体框架错误

  •  6
  • Omar  · 技术社区  · 16 年前

    与2010年测试版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中属于“文本非空”类型。

    我的操作将检查该值是否为空,如果为空,则会添加一个模型错误,但提交表单后我会得到该错误。

    8 回复  |  直到 10 年前
        1
  •  8
  •   Craig Stuntz    16 年前

    您是否直接绑定到实体?看起来不错。所以你有两个选择:

    1. 编写自定义模型绑定器,该绑定器转换空字符串。
    2. 绑定到允许空值的编辑模型,然后在将值复制到操作中的实体时将其更改为空字符串。

    我个人会选择2。我认为你应该总是使用视图/编辑模型,这是一个很好的例子。

        2
  •  4
  •   Community Mohan Dere    8 年前

    我也有同样的问题。我四处找了找工作。它将此问题描述为在所需字段验证之前进行的EF验证所导致的问题。它还显示了如何使用 [DisplayFormat] 标签。希望这对你有帮助。

    以下是问题和解决方法的链接:

    Server-side validation of a REQUIRED String Property in MVC2 Entity Framework 4 does not work

        3
  •  2
  •   Grant Winney    12 年前

    这是MVC2和实体框架4的问题,还是设计的问题?对于日期时间不可为空(必需)的字段,似乎可以很好地验证ef属性,而数字字段和字符串字段的数据类型验证可以在不使用ViewModels的情况下工作。

    我用一个简单的foobar表重新创建了这个问题,在SLQ2008中使用了一个名为barname的不可为空的varchar(50)列。我从该数据库生成了EF模型,并迅速为foobar实体添加了控制器和创建视图。如果我尝试在不输入属性barname值的情况下发布到create操作,vs会在模型的designer.cs文件中逐步进入异常(就像上面的一样)。当我试图跳过异常时,验证消息会显示在表单上,并且字段以粉红色突出显示。

    似乎有什么东西没有按正确的顺序发射。因为异常发生在vs进入httppost创建方法之前。

    我发现ASP.NET MVCMusicStore示例中的代码很有用。 http://mvcmusicstore.codeplex.com/releases/view/44445#DownloadId=119336

    绑定到视图模型似乎解决了这个问题。

    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; }
            }
        }
    }
    
        4
  •  1
  •   Svavar    13 年前

    阿什什·谢基亚的回答帮助了我。我将这个属性添加到属性中,现在它可以工作了。

    [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();
            }
        }
    
        5
  •  1
  •   Daniel DiPaolo    13 年前

    导入命名空间:

    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,在验证中显示错误消息,并且不会在服务器上以空值失败。

        6
  •  1
  •   GDP Danny    13 年前

    我有同样的问题,通过 false true 这样地:

    Line 4502:
    _Text = StructuralObject.SetValidValue(value, false);
    
        7
  •  0
  •   Kind Contributor    13 年前

    我自己也遇到了同样的问题,来到这里寻找解决办法。但是,答案可以得到增强。

    svavar和hackitmngr走在了正确的道路上,但是两者的结合给出了最好的结果。您不想去修饰生成的类,因为您可能会在修改ef模型时丢失自定义更改。

    [元数据类型(typeof(myTableMetadata))] 公共分部类MyTable { //唱片集类的验证规则

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

    解决双方之间的任何争论。我想说斯瓦瓦的是直接的答案,哈基特姆格是增强。

    对我来说太好了!

        8
  •  0
  •   user2409985    10 年前

    我将storeGeneratedPattern属性设置为每个字段的计算值,它为我解决了这个问题。

    推荐文章