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

时间:2009-11-22 04:32:34

标签: asp.net-mvc-2 .net-4.0 .net-4.0-beta-2

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

该属性名为“Text”,在MS SQL 2008中的类型为“text NOT NULL”。

我的操作将检查该值是否为nullorempty,如果是,则会添加模型错误,但是一旦我提交表单,我就会收到错误。

8 个答案:

答案 0 :(得分:8)

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

  1. 编写一个自定义模型绑定器,用于转换null - >空字符串。
  2. 绑定到允许空值的编辑模型,然后在将值复制到操作中的实体时将其更改为空字符串。
  3. 我个人选择#2。我认为你应该总是使用视图/编辑模型,这是一个很好的例子。

答案 1 :(得分:4)

我遇到了同样的问题。我环顾四周,在这里找到了一份工作。它描述了在必填字段验证之前由EF验证引起的问题。它还显示了我们如何使用[DisplayFormat]标记解决此问题。希望这会对你有所帮助。

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

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

答案 2 :(得分:2)

这是MVC2和Entity Framework 4的问题还是这个设计?似乎EF属性的验证对于datetime非可空(必需)字段工作正常,并且数字与字符串字段的数据类型验证正在工作,而不必使用ViewModel。

我使用一个简单的FOOBAR表在slq 2008中使用名为barName的单个,不可为空的varchar(50)列重新创建了该问题。我从该数据库生成了EF模型并快速添加了一个控制器和一个CREATE视图。 FOOBAR实体。如果我尝试在不输入属性barName的值的情况下POST到CREATE操作,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; }
        }
    }
}

答案 3 :(得分:1)

我遇到了同样的问题并通过将false改为true来解决此问题:

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

答案 4 :(得分:1)

Ashish Shakya的回答帮助了我。我将此属性添加到属性中,现在它可以正常工作。

[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)

导入命名空间:

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服务器上不会失败。

答案 6 :(得分:0)

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

Svavar和HackITMngr走在正确的轨道上,但两者结合起来都能带来最好的结果。您不希望修改生成的类,因为您可能会在修改EF模型时丢失自定义更改。

[MetadataType(typeof运算(MyTableMetaData))]     公共部分类MyTable     {         // Album类的验证规则

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

解决两者之间的任何争论。我说Svavar是直接答案,HackITMngr是增强功能。

非常适合我!

答案 7 :(得分:0)

我将StoreGeneratedPattern属性设置为每个字段的Computed,它为我解决了问题。