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

发布于 2024-08-12 09:43:10 字数 632 浏览 10 评论 0原文

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”。

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

VS 2010 Beta 2, .NET 4.

In my ASP.NET MVC 2 application, when I submit a form to an action method that accepts an object created by the entity framework, I get the following error:

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

The property is called "Text" and is of type "text NOT NULL" in MS SQL 2008.

My action will check if the value is nullorempty, if it is, a model error will be added, but I get the error as soon as I submit the form.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

二货你真萌 2024-08-19 09:43:10

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

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

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

Are you binding directly to the entity? Sure looks like it. So you have two choices:

  1. Write a custom model binder which translates null -> empty string.
  2. Bind to an edit model which allows nulls instead, and then change this to empty string when you copy the values to the entity in the action.

I'd choose #2, personally. I think you should always use view/edit models, and this is a great example of why.

轮廓§ 2024-08-19 09:43:10

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

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

MVC2 实体框架 4 中所需字符串属性的服务器端验证不起作用

I was having the same problem. I looked around and found a work around here. It describes the problem as being caused by the EF validation taking place before the Required field validation. It also shows how we can work around this problem by using a [DisplayFormat] Tag. Hope this will help you.

Here's the link to the question and the workaround:

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

-小熊_ 2024-08-19 09:43:10

这是 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; }
        }
    }
}

Is this an issue with the MVC2 and Entity Framework 4 or is this by design? It appears that validation of EF properties works fine for datetime non-nullable (required) fields and data type validation of numeric versus string fields is working without having to use ViewModels.

I recreated the issue using with a simple FOOBAR table using a single, non-nullable varchar(50) column called barName in slq 2008. I generated the EF model from that database and quickly added a controller and a CREATE view for the FOOBAR entity. If I try to POST to the CREATE action without entering in a value for the property barName, VS steps into an exception within the designer.cs file of the model (just like the one above). When, I try to step past the exception, the validation message shows up on the form and the field is highlighted in pink.

It seems like something is not firing in the correct sequence. Because the exception occurs before VS steps into the HTTPPOST CREATE method.

I found the code from the ASP.Net MvcMusicStore sample helpful. http://mvcmusicstore.codeplex.com/releases/view/44445#DownloadId=119336

It appears that binding to the ViewModel fixes the issue.

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; }
        }
    }
}
在你怀里撒娇 2024-08-19 09:43:10

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

Ashish Shakya's answer helped me. I added this attribute to the property and now it works.

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

So it looks like this:

    [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();
        }
    }
秋意浓 2024-08-19 09:43:10

导入命名空间:

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 失败。

Import the namespace:

using System.ComponentModel.DataAnnotations;

And add the attribute property [Required]

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

Thus ModelState.IsValid equals false, showing error message in the validation and will not fail on the server with Null.

疯狂的代价 2024-08-19 09:43:10

我遇到了同样的问题,并通过将 false 设为 true 来修复它,如下所示:

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

I had the same problem and fixed it by making false to true like this:

Line 4502:
_Text = StructuralObject.SetValidValue(value, false);
暮凉 2024-08-19 09:43:10

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

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

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

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

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

对我来说效果很好!

I just had the same problem myself, and came here to find the solution. However, the answer can be enhanced.

Svavar's and HackITMngr were on the right track, however combining both gives the best outcome. You don't want to go decorating the generated classes, as you risk losing your custom changes upon modifications to the EF model.

[MetadataType(typeof(MyTableMetaData))]
public partial class MyTable
{
// Validation rules for the Album class

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

To settle any arguments between the two. I'd say Svavar's was the direct answer, HackITMngr was the enhancement.

Works great for me!

你在看孤独的风景 2024-08-19 09:43:10

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

I set StoreGeneratedPattern property as Computed for each field and it solved the problem for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文