为了账号安全,请及时绑定邮箱和手机立即绑定

一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationError”属性

一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationError”属性

饮歌长啸 2019-06-20 16:01:55
一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationError”属性当用代码优先方法播种我的数据库时,我遇到了这个错误。一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationError”属性。老实说,我不知道如何检查验证错误的内容。VisualStudio向我展示了它是一个包含8个对象的数组,因此有8个验证错误。这是与我以前的模型一起工作的,但是我做了一些修改,我在下面解释如下:我有一个名为Status的枚举,我将它更改为一个名为Status的类。我将类ApplicantsPositionHistory更改为同一个表的2个外键对不起,代码太长了,但我得把它全部粘贴起来。异常将在以下代码的最后一行中抛出。namespace Data.Model{       public class Position     {         [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]            public int PositionID { get; set; }         [Required(ErrorMessage = "Position name is required.")]         [StringLength(20, MinimumLength = 3, ErrorMessage = "Name should not be longer than 20 characters.")]         [Display(Name = "Position name")]                       public string name { get; set; }         [Required(ErrorMessage = "Number of years is required")]          [Display(Name = "Number of years")]                 public int yearsExperienceRequired { get; set; }         public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }     }     public class Applicant     {         [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]               public int ApplicantID { get; set; }         [Required(ErrorMessage = "Name is required")]          [StringLength(20, MinimumLength = 3, ErrorMessage="Name should not be longer than 20 characters.")]         [Display(Name = "First and LastName")]         public string name { get; set; }         [Required(ErrorMessage = "Telephone number is required")]          [StringLength(10, MinimumLength = 3, ErrorMessage = "Telephone should not be longer than 20 characters.")]         [Display(Name = "Telephone Number")]         public string telephone { get; set; }         [Required(ErrorMessage = "Skype username is required")]          [StringLength(10, MinimumLength = 3, ErrorMessage = "Skype user should not be longer than 20 characters.")]         [Display(Name = "Skype Username")]     }
查看完整描述

3 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

老实说,我不知道如何检查验证错误的内容。VisualStudio向我展示了它是一个包含8个对象的数组,因此有8个验证错误。

实际上,如果在调试期间钻入Visualstudio中的数组,您应该会看到错误。但是,您也可以捕获异常,然后将错误写入某个日志存储区或控制台:

try{
    // Your code...
    // Could also be before try if you know the exception occurs in SaveChanges

    context.SaveChanges();}catch (DbEntityValidationException e){
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
            eve.Entry.Entity.GetType().Name, eve.Entry.State);
        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;}

EntityValidationErrors是一个集合,它表示无法成功验证的实体和内部集合。ValidationErrors每个实体都是属性级别上的错误列表。

这些验证消息通常有助于找到问题的根源。

编辑

几点小小的改进:

这个价值在内部循环中可以包括以下违规属性:

        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                ve.PropertyName,
                eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                ve.ErrorMessage);
        }

同时调试Debug.Write可能比Console.WriteLine因为它适用于所有类型的应用程序,而不仅仅是控制台应用程序(感谢@Bart在下面的注释中给出的说明)。

用于正在生产和使用的web应用程序埃尔马对于异常日志记录,对我来说创建自定义异常和覆盖非常有用。SaveChanges才能抛出这个新的异常。

自定义异常类型如下所示:

public class FormattedDbEntityValidationException : Exception{
    public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
        base(null, innerException)
    {
    }

    public override string Message
    {
        get        {
            var innerException = InnerException as DbEntityValidationException;
            if (innerException != null)
            {
                StringBuilder sb = new StringBuilder();

                sb.AppendLine();
                sb.AppendLine();
                foreach (var eve in innerException.EntityValidationErrors)
                {
                    sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().FullName, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                            ve.PropertyName,
                            eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                            ve.ErrorMessage));
                    }
                }
                sb.AppendLine();

                return sb.ToString();
            }

            return base.Message;
        }
    }}

SaveChanges可以用下列方式覆盖:

public class MyContext : DbContext{
    // ...

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            var newException = new FormattedDbEntityValidationException(e);
            throw newException;
        }
    }}

几点意见:

  • Elmah在Web界面或发送的电子邮件中显示的黄色错误屏幕(如果您已经配置了的话)现在将验证细节直接显示在消息的顶部。

  • 覆盖Message属性在自定义异常中,而不是覆盖。ToString()具有标准的ASP.NET“死亡黄屏幕(YSOD)”也显示此消息的好处。与Elmah相比,YSOD显然不使用ToString(),但两者都显示Message财产。

  • 包装原件DbEntityValidationException作为内部异常,可以确保原始堆栈跟踪仍然可用,并显示在Elmah和YSOD中。

  • 通过在行上设置断点throw newException;您可以简单地检查newException.Message属性作为文本,而不是钻入验证集合,这有点尴尬,而且似乎对每个人都不容易工作(请参阅下面的注释)。


查看完整回答
反对 回复 2019-06-20
  • 3 回答
  • 0 关注
  • 1585 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信