6

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

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

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

4

8 回答 8

9

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

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

我个人会选择#2。我认为您应该始终使用查看/编辑模型,这是一个很好的例子。

于 2009-11-23T13:58:08.903 回答
4

我遇到了同样的问题。我环顾四周,发现这里有一个工作。它将问题描述为由在必填字段验证之前进行的 EF 验证引起的。它还展示了我们如何通过使用[DisplayFormat]标签来解决这个问题。希望这会帮助你。

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

MVC2 Entity Framework 4 中 REQUIRED 字符串属性的服务器端验证不起作用

于 2010-10-03T15:37:43.643 回答
3

我遇到了同样的问题并通过如下方式解决了falsetrue

Line 4502:
_Text = StructuralObject.SetValidValue(value, false);
于 2012-04-24T19:35:47.337 回答
2

这是 MVC2 和 Entity Framework 4 的问题还是设计使然?似乎 EF 属性的验证适用于日期时间不可为空(必需)的字段,并且数字与字符串字段的数据类型验证正在工作,而无需使用 ViewModel。

我在 slq 2008 中使用一个名为 barName 的单个不可为空的 varchar(50) 列使用简单的 FOOBAR 表重新创建了该问题。我从该数据库生成了 EF 模型,并快速为 FOOBAR 实体添加了一个控制器和一个 CREATE 视图。如果我尝试 POST 到 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; }
        }
    }
}
于 2010-06-26T01:39:23.313 回答
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 失败。

于 2012-07-19T23:23:59.127 回答
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();
        }
    }
于 2012-05-24T09:24:22.873 回答
0

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

于 2015-03-02T14:46:55.097 回答
0

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

Svavar's 和 HackITMngr 走在正确的轨道上,但是将两者结合起来会产生最好的结果。您不想去装饰生成的类,因为您可能会在修改 EF 模型时丢失自定义更改。

[MetadataType(typeof(MyTableMetaData))] public partial class MyTable { // Album 类的验证规则

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

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

对我有用!

于 2013-01-15T03:08:03.850 回答