Не вдалося перевірити для однієї чи кількох організацій. Докладніше див. У властивості EntityValidationErrors


804

У мене виникає ця помилка під час виведення моєї бази даних з кодом першого підходу.

Не вдалося перевірити для однієї чи кількох організацій. Докладніше див. У властивості EntityValidationErrors.

Якщо чесно, я не знаю, як перевірити зміст помилок перевірки. Visual Studio показує мені, що це масив з 8 об’єктами, тому 8 помилок перевірки.

Це працювало з моєю попередньою моделлю, але я внесла кілька змін, які я поясню нижче:

  • У мене з'явився перелік під назвою Status, я змінив його на клас під назвою Status
  • Я змінив клас ExamantsPositionHistory, щоб мати 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")]
        public string skypeuser { get; set; }

        public byte[] photo { get; set; }

        public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
    }

    public class ApplicantPosition
    {
        [Key]
        [Column("ApplicantID", Order = 0)]
        public int ApplicantID { get; set; }

        [Key]
        [Column("PositionID", Order = 1)]
        public int PositionID { get; set; }

        public virtual Position Position { get; set; }

        public virtual Applicant Applicant { get; set; }

        [Required(ErrorMessage = "Applied date is required")] 
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date applied")]     
        public DateTime appliedDate { get; set; }

        [Column("StatusID", Order = 0)]
        public int StatusID { get; set; }

        public Status CurrentStatus { get; set; }

        //[NotMapped]
        //public int numberOfApplicantsApplied
        //{
        //    get
        //    {
        //        int query =
        //             (from ap in Position
        //              where ap.Status == (int)Status.Applied
        //              select ap
        //                  ).Count();
        //        return query;
        //    }
        //}
    }

    public class Address
    {
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Country should not be longer than 20 characters.")]
        public string Country { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "City  should not be longer than 20 characters.")]
        public string City { get; set; }

        [StringLength(50, MinimumLength = 3, ErrorMessage = "Address  should not be longer than 50 characters.")]
        [Display(Name = "Address Line 1")]     
        public string AddressLine1 { get; set; }

        [Display(Name = "Address Line 2")]
        public string AddressLine2 { get; set; }   
    }

    public class ApplicationPositionHistory
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int ApplicationPositionHistoryID { get; set; }

        public ApplicantPosition applicantPosition { get; set; }

        [Column("oldStatusID")]
        public int oldStatusID { get; set; }

        [Column("newStatusID")]
        public int newStatusID { get; set; }

        public Status oldStatus { get; set; }

        public Status newStatus { get; set; }

        [StringLength(500, MinimumLength = 3, ErrorMessage = "Comments  should not be longer than 500 characters.")]
        [Display(Name = "Comments")]
        public string comments { get; set; }

        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date")]     
        public DateTime dateModified { get; set; }
    }

    public class Status
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int StatusID { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "Status  should not be longer than 20 characters.")]
        [Display(Name = "Status")]
        public string status { get; set; }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.IO;

namespace Data.Model
{
    public class HRContextInitializer : DropCreateDatabaseAlways<HRContext>
    {
        protected override void Seed(HRContext context)
        {
            #region Status
            Status applied = new Status() { status = "Applied" };
            Status reviewedByHR = new Status() { status = "Reviewed By HR" };
            Status approvedByHR = new Status() { status = "Approved by HR" };
            Status rejectedByHR = new Status() { status = "Rejected by HR" };
            Status assignedToTechnicalDepartment = new Status() { status = "Assigned to Technical Department" };
            Status approvedByTechnicalDepartment = new Status() { status = "Approved by Technical Department" };
            Status rejectedByTechnicalDepartment = new Status() { status = "Rejected by Technical Department" };

            Status assignedToGeneralManager = new Status() { status = "Assigned to General Manager" };
            Status approvedByGeneralManager = new Status() { status = "Approved by General Manager" };
            Status rejectedByGeneralManager = new Status() { status = "Rejected by General Manager" };

            context.Status.Add(applied);
            context.Status.Add(reviewedByHR);
            context.Status.Add(approvedByHR);
            context.Status.Add(rejectedByHR);
            context.Status.Add(assignedToTechnicalDepartment);
            context.Status.Add(approvedByTechnicalDepartment);
            context.Status.Add(rejectedByTechnicalDepartment);
            context.Status.Add(assignedToGeneralManager);
            context.Status.Add(approvedByGeneralManager);
            context.Status.Add(rejectedByGeneralManager); 
            #endregion    

            #region Position
            Position netdeveloper = new Position() { name = ".net developer", yearsExperienceRequired = 5 };
            Position javadeveloper = new Position() { name = "java developer", yearsExperienceRequired = 5 };
            context.Positions.Add(netdeveloper);
            context.Positions.Add(javadeveloper); 
            #endregion

            #region Applicants
            Applicant luis = new Applicant()
            {
                name = "Luis",
                skypeuser = "le.valencia",
                telephone = "0491732825",
                photo = File.ReadAllBytes(@"C:\Users\LUIS.SIMBIOS\Documents\Visual Studio 2010\Projects\SlnHR\HRRazorForms\Content\pictures\1.jpg")
            };

            Applicant john = new Applicant()
            {
                name = "John",
                skypeuser = "jo.valencia",
                telephone = "3435343543",
                photo = File.ReadAllBytes(@"C:\Users\LUIS.SIMBIOS\Documents\Visual Studio 2010\Projects\SlnHR\HRRazorForms\Content\pictures\2.jpg")
            };

            context.Applicants.Add(luis);
            context.Applicants.Add(john); 
            #endregion

            #region ApplicantsPositions
            ApplicantPosition appicantposition = new ApplicantPosition()
            {
                Applicant = luis,
                Position = netdeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };

            ApplicantPosition appicantposition2 = new ApplicantPosition()
            {
                Applicant = john,
                Position = javadeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };        

            context.ApplicantsPositions.Add(appicantposition);            
            context.ApplicantsPositions.Add(appicantposition2); 
            #endregion

            context.SaveChanges(); --->> Error here
        }
    }
}

Відповіді:


1237

Якщо чесно, я не знаю, як перевірити зміст помилок перевірки. Visual Studio показує мені, що це масив з 8 об’єктами, тому 8 помилок перевірки.

Насправді ви повинні побачити помилки, якщо під час налагодження ви переглядаєте цей масив у Visual studio. Але ви також можете зловити виняток, а потім виписати помилки в деякий магазин журналів або консоль:

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 за його примітку в коментарях нижче).

Для веб-додатків, які випускаються та використовують Elmah для реєстрації винятків, мені виявилося дуже корисним створити спеціальний виняток та перезаписати 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 у веб-інтерфейсі або у надісланих електронних листах (якщо ви це налаштували), тепер відображає дані про перевірку безпосередньо у верхній частині повідомлення.

  • Переписування Messageвластивості у власному винятку замість перезапису ToString()має перевагу в тому, що стандартне ASP.NET "Жовтий екран смерті (YSOD)" також відображає це повідомлення. На відміну від Elmah, YSOD, очевидно, не використовує ToString(), але обидва відображають Messageвластивість.

  • Обгортання оригіналу DbEntityValidationExceptionяк внутрішнього виключення гарантує, що початковий слід стека все ще буде доступний і відображатиметься в Elmah та YSOD.

  • Встановивши точку перерви на лінії, throw newException;ви можете просто ознайомитись із newException.Messageвластивістю як текстом замість того, щоб свердлити в колекції перевірки, що трохи незручно і, здається, не працює легко для всіх (див. Коментарі нижче).


87
Свердлювання винятку нічого не робить. Це просто говорить, що є DbEntityValidationResult, але не дозволяє вам розширюватися !!
Шумій

30
@Shumii Дивіться цю відповідь, щоб розширити виняток.
Кавін ВонДейлен

18
Просто для розширення елегантного рішення. Ви можете замінити метод збереження змін у вашому власному класі DbContext, а потім додати спробувати блок catch, де блок спробу просто намагатись зберегти (base.SaveChanges ()), а блок вилучення вловлює лише DbEntityValidationException. Таким чином, вам не потрібно додавати його в кожному місці, де ви зберігаєте свої зміни.
Мілтон

7
Це врятувало моє сало не раз. Я міг схвалити лише один раз. Хотіли, щоб вони дозволили мені підняти кожен раз, коли я це копіював і вставляв.
Деймон Дрейк

5
+2 для коду. Справді, рятувальник :) -1 для використання Console.WriteLine, я вважаю, що більше людей пишуть веб-проекти, а нині консольні програми та Debug.Writeпрацюють в обох ...
Барт

459

Ви можете це зробити з Visual Studio під час налагодження, не записуючи жодного коду, навіть блоку лову.

Просто додайте годинник з назвою:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

Вираз годинника $exceptionвідображає будь-які винятки, кинуті в поточному контексті, навіть якщо він не був спійманий і призначений змінній.

На основі http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/


39
+1 Шлях краще рішення і не потребує змін у коді. Класно
Юстас

4
+1 це дуже, дуже зручно! Вам навіть не потрібно мати блок спробувати / ловити. Просто вставте це у список спостереження, коли VS перерва та вуаля.
onietiman

40
кілька разів на рік я забуваю, як це зробити, і знаходжу цю відповідь
Джастін Мур

3
@zairja Я не перевіряв його на vb.net, але, схоже, змінна визначена і для vb.net, а також у msdn.microsoft.com/en-us/library/ms164891.aspx , однак, можливо, це не так визначено для vb.net, і замість цього, ймовірно, слід робити DirectCast ($ виняток, System.Data.Entity.Validation.DbEntityValidationException)
yoel halb

2
Я знаю, що "спасибі" не вітаються в коментарях, але заради того, щоб запобігти мені витрачений час ... дякую!
Лютер

105

Це фактично може зробити це без необхідності писати код:

У блоці вилову додайте крапку в наступному рядку коду:

catch (Exception exception)
{

}

Тепер якщо ви наведіть на exceptionнього вказівник або додаєте його до, Watchа потім перейдіть до деталей про винятки, як показано нижче; ви побачите, який конкретний стовпець (и) викликає / викликає проблему, оскільки ця помилка, як правило, виникає при порушенні обмеження таблиці.

введіть тут опис зображення

Велике зображення


4
Цей підхід дуже простий і користується IDE :)
dsnunez

3
Це хороше рішення, тому що це швидко, просто, використовує IDE і заощадив мені тону часу.
maxshuty

2
Мені подобається такий спосіб "Як бути кодером і не робити код"
відкрито та безкоштовно

1
Дякую. Це просто, але дивовижно переглядати виняток за допомогою IDE.
Thomas.Benz

ідеальне рішення
Neeraj Singh Chouhan

46

Ось як можна перевірити вміст EntityValidationErrors у Visual Studio (без написання зайвого коду), тобто під час налагодження в IDE .

Проблема?

Ви праві, відладчик програми View Visual Studio Popup не показує фактичних помилок всередині EntityValidationErrorsколекції.

введіть тут опис зображення

Рішення!

Просто додайте наступне вираз у вікно швидкого перегляду та натисніть кнопку Переоцінити .

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

У моєму випадку подивіться, як я в змозі розширити колекцію ValidationErrors ListвсерединіEntityValidationErrors

введіть тут опис зображення

Список літератури: допис у блозі mattrandle.me , відповідь @ yoel


3
чому це не виправлено? це повинно показати помилку не щось інше
Geomorillo

2
Помилка перевірки показує помилку властивості, напр. тематичне поле обов'язкове, хороша відповідь, дякую
hamzeh.hanandeh

1
Чудово! Це врятувало мою ніч! :)
Патрік

1
це розумний спосіб візуалізації точної помилки в годиннику ... дякую!
Qwerty

39

Швидкий спосіб побачити першу помилку, навіть не додавши годинник, ви можете вставити її в Негайне вікно:

((System.Data.Entity.Validation.DbEntityValidationException)$exception)
    .EntityValidationErrors.First()
    .ValidationErrors.First()

1
Ви також можете використовувати $ exception.EntityValidationErrors.SelectMany (х => x.ValidationErrors) .Select (х => x.ErrorMessage) , щоб отримати всі з них :) імхо , використовуючи негайне вікно є найкращою відповіддю
chrispepper1989

15

Для всіх, хто працює в VB.NET

Try
Catch ex As DbEntityValidationException
    For Each a In ex.EntityValidationErrors
        For Each b In a.ValidationErrors
            Dim st1 As String = b.PropertyName
            Dim st2 As String = b.ErrorMessage
        Next
    Next
End Try

12

Поки ви перебуваєте в режимі налагодження в catch {...}блоці, відкрийте вікно "QuickWatch" ( ctrl+ alt+ q) і вставте туди:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

або:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

Якщо ви не перебуваєте у спробі / лові або не маєте доступу до об’єкта винятку.

Це дозволить спуститися в ValidationErrorsдерево. Це найпростіший спосіб я зрозуміти ці помилки.


10

Якщо ви просто вловлюєте загальний виняток, це може вам принести користь, якщо це можна зробити як DbEntityValidationException . Цей тип виключення має властивість Помилки перевірки, і продовжуючи розширювати свій шлях до них, ви знайдете всі проблеми.

Наприклад, якщо ви поставите крапку в улові, ви можете кинути таке в годинник:

((System.Data.Entity.Validation.DbEntityValidationException ) ex)

Прикладом помилки є те, що якщо поле не дозволяє нульовим знакам, а у вас є нульова рядок, ви побачите, що воно говорить про те, що поле обов'язкове.


9

просто перевірте довжину поля таблиці вашої бази даних. Ваш текст введення більший, ніж довжина типу даних поля стовпця


9

У налагодженні ви можете ввести це у полі запису виразника QuickWatch:

context.GetValidationErrors()

8

Відповідь від @Slauma дійсно чудова, але я виявив, що вона не працює, коли властивість ComplexType недійсна.

Наприклад, скажіть, що у вас є властивість Phoneскладного типу PhoneNumber. Якщо AreaCodeвластивість недійсна, назва власності в ve.PropertyNames"Phone.AreaCode". Це призводить eve.Entry.CurrentValues<object>(ve.PropertyName)до відмови дзвінка .

Щоб виправити це, ви можете розділити ім’я властивості на кожне ., а потім повторити через отриманий масив імен властивостей. Нарешті, прийшовши на дно ланцюга, ви можете просто повернути вартість майна.

Нижче FormattedDbEntityValidationExceptionклас @ Slauma з підтримкою ComplexTypes.

Насолоджуйтесь!

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

    public override string Message
    {
        get
        {
            var innerException = InnerException as DbEntityValidationException;
            if (innerException == null) return base.Message;

            var 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)
                {
                    object value;
                    if (ve.PropertyName.Contains("."))
                    {
                        var propertyChain = ve.PropertyName.Split('.');
                        var complexProperty = eve.Entry.CurrentValues.GetValue<DbPropertyValues>(propertyChain.First());
                        value = GetComplexPropertyValue(complexProperty, propertyChain.Skip(1).ToArray());
                    }
                    else
                    {
                        value = eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName);
                    }
                    sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                        ve.PropertyName,
                        value,
                        ve.ErrorMessage));
                }
            }
            sb.AppendLine();

            return sb.ToString();
        }
    }

    private static object GetComplexPropertyValue(DbPropertyValues propertyValues, string[] propertyChain)
    {
        var propertyName = propertyChain.First();
        return propertyChain.Count() == 1 
            ? propertyValues[propertyName] 
            : GetComplexPropertyValue((DbPropertyValues)propertyValues[propertyName], propertyChain.Skip(1).ToArray());
    }
}

1
Я не можу повірити, що більшість людей не підтримали цього, оскільки це дуже реальний сценарій, і він мене змусив останні дві ночі. Ви знаєте, що відчуття, яке ви отримуєте, коли розумієте, що обробка помилок - це те, що насправді кидає помилку? Тьфу.
DJ Grossman

7

Зауважте, що Entity.GetType().BaseType.Nameвказується вказане ім'я типу, а не те, у якому в ньому є всі шістнадцяткові цифри.


7

Відповідь Пер @ Слауми та пропозиція @ Мілтона, я розширив спеціальний метод збереження базового класу за допомогою методу try / catch, який буде обробляти (і, отже, входити в наш журнал помилок!) Подібними винятками.

// Where `BaseDB` is your Entities object... (it could be `this` in a different design)
public void Save(bool? validateEntities = null)
{
    try
    {
        //Capture and set the validation state if we decide to
        bool validateOnSaveEnabledStartState = BaseDB.Configuration.ValidateOnSaveEnabled;
        if (validateEntities.HasValue)
            BaseDB.Configuration.ValidateOnSaveEnabled = validateEntities.Value;

        BaseDB.SaveChanges();

        //Revert the validation state when done
        if (validateEntities.HasValue)
            BaseDB.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabledStartState;
    }
    catch (DbEntityValidationException e)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var eve in e.EntityValidationErrors)
        {
            sb.AppendLine(string.Format("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)
            {
                sb.AppendLine(string.Format("- Property: \"{0}\", Error: \"{1}\"",
                                            ve.PropertyName,
                                            ve.ErrorMessage));
            }
        }
        throw new DbEntityValidationException(sb.ToString(), e);
    }
}

1
Ви можете використовувати sb.AppendFormat () безпосередньо
Bastien Vandamme

1
Вам також потрібно буде додати свій власний новий рядок, якщо ви використовуєте AppendFormat.
Jocull

7

Мені довелося написати це у вікно негайного виду: 3

(((exception as System.Data.Entity.Validation.DbEntityValidationException).EntityValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbEntityValidationResult>)[0].ValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbValidationError>)[0]

щоб заглибитися в точну помилку!


6

Використовуючи відповідь @Slauma, я зробив фрагмент коду (оточення фрагмента) для кращого використання.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>SurroundsWith</SnippetType>
      </SnippetTypes>
      <Title>ValidationErrorsTryCatch</Title>
      <Author>Phoenix</Author>
      <Description>
      </Description>
      <HelpUrl>
      </HelpUrl>
      <Shortcut>
      </Shortcut>
    </Header>
    <Snippet>
      <Code Language="csharp"><![CDATA[try
{
    $selected$ $end$
}
catch (System.Data.Entity.Validation.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;
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

5

Зробіть виняток у спробу лову, а потім швидкий перегляд або ctrl + d & ctrl + q, і ви можете перейти до EntityValidationErrors.


5

Просто кидаю два мої центи у ...

У моєму dbConfiguration.cs я люблю переносити свій контекст.SaveChanges () метод спробувати / ловити та створити вихідний текстовий файл, який дозволяє мені чітко читати помилки (і), і цей код також їх відмічає - зручно, якщо ви зіткнутися з декількома помилками в різний час!

        try
        {
            context.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            //Create empty list to capture Validation error(s)
            var outputLines = new List<string>();

            foreach (var eve in e.EntityValidationErrors)
            {
                outputLines.Add(
                    $"{DateTime.Now}: Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:");
                outputLines.AddRange(eve.ValidationErrors.Select(ve =>
                    $"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\""));
            }
            //Write to external file
            File.AppendAllLines(@"c:\temp\dbErrors.txt", outputLines);
            throw;
        }

5

Що я знайшов ... коли я отримав помилку "EntityValidationErrors", це те, що .... у мене в базі даних "db1" в таблиці "tbladdress" є поле "address1", яке має розмір 100 (тобто адреса varchar (100) null), і я передав значення більше 100 символів ... і це призводило до помилок під час збереження даних у базі даних ....

Тому ви повинні перевірити дані, які ви передаєте в поле.


1
Я високо ціную цю відповідь, тому що вона фактично допомогла мені вирішити свою помилку. Таблиця, до якої я економив у своєму db, мала всі not nullстовпці, тож як тільки я додав дані до всіх елементів до мого, db.SaveChanges()я не отримав помилок.
BinaryJoe01

3

Це працює для мене.

var modelState = ModelState.Values;
if (!ModelState.IsValid)
{
    return RedirectToAction("Index", "Home", model);
}

Поставте точку перелому, якщо заява. Потім ви можете перевірити modelState у вікнах налагодження. На кожному значенні ви можете бачити, чи є помилка і навіть повідомлення про помилку. Це воно. Коли він вам більше не потрібен, просто видаліть або прокоментуйте рядок.

Сподіваюся, це допоможе.

За запитом я можу надати детальний знімок екрана у вікні налагодження.


3

Як вже згадувалося в інших публікаціях, просто виловіть виняток у класі DbEntityValidationException. Що дасть вам заробіток, який вам потрібен під час помилок.

 try
 {
  ....
 }
 catch(DbEntityValidationException ex)
 {
  ....
 }

2

Я раніше стикався з цією помилкою

коли я намагався оновити конкретне поле моєї моделі у фреймворці сутності

Letter letter = new Letter {ID = letterId, ExportNumber = letterExportNumber,EntityState = EntityState.Modified};
LetterService.ChangeExportNumberfor(letter);
//----------


public int ChangeExportNumber(Letter letter)
    {
        int result = 0;
        using (var db = ((LettersGeneratorEntities) GetContext()))
        {
            db.Letters.Attach(letter);
            db.Entry(letter).Property(x => x.ExportNumber).IsModified = true;
            result += db.SaveChanges();
        }
        return result;
    }

і відповідно до наведених відповідей

Я знайшов повідомлення про перевірку The SignerName field is required.

яке вказує на поле в моїй моделі

і коли я перевірив свою схему бази даних, яку я знайшов

введіть тут опис зображення

таким чином, з курежу ValidationException має право підвищувати

і відповідно до цього поля, я хочу, щоб це було зведене, (я не знаю, як я це зіпсував)

тому я змінив це поле, щоб дозволити Null, і завдяки цьому мій код більше не дасть мені цієї помилки

тож ця помилка, можливо, станеться, якщо ви визнаєте недійсними цілісність ваших даних у вашій базі даних


1
Потрібно ставити виняток чи ні, тут не суть справи. Далі ви тут виріжте кілька куточків. Коли в схемі бази даних потрібне поле, вам потрібно більше, ніж те, щоб DbEntityValidationExceptionпідняти.
Герт Арнольд

2

Будь ласка, перевірте значення полів, які ви передаєте, чи дійсні та відповідно до полів бази даних. Наприклад, кількість символів, переданих у певному полі, менше символів, визначених у полі таблиці бази даних.


1

Якщо ви використовуєте IIS з Windows Authentication and Entity Framework , будьте обережні authorize.

Я намагався POSTбез авторизації, і це не вийшло, і отримати цю помилку db.SaveChangesAsync();, тоді як усі інші дієслова GETі DELETEпрацювали.

Але коли я додав AuthorizeAttribute як анотацію, вона спрацювала.

[Authorize]
public async Task<IHttpActionResult> Post(...){
....
}

1

Ось ще один спосіб зробити це замість використання циклів foreach для огляду всередині EntityValidationErrors. Звичайно, ви можете відформатувати повідомлення на свій смак:

try {
        // your code goes here...
    } 
catch (DbEntityValidationException ex) 
    {
        Console.Write($"Validation errors: {string.Join(Environment.NewLine, ex.EntityValidationErrors.SelectMany(vr => vr.ValidationErrors.Select(err => $"{err.PropertyName} - {err.ErrorMessage}")))}", ex);
        throw;
    }

1

У моєму випадку це було через те, що довжина поля бази даних менша за довжину поля введення.

таблиця бази даних

create table user(
  Username nvarchar(5) not  null
);

Мій внесок

User newUser = new User()
{
   Username = "123456"
};

значення Username lengthдорівнює 5, яке дорівнює lessthan6

... це може комусь допомогти


0

Перевірте, чи є Not Nullу вас обмеження в стовпцях таблиці, і чи не передає вам значення для цього стовпця під час операцій вставлення / оновлення. Це спричиняє цей виняток в рамках сутності.


0

Я також зіткнувся з тією ж проблемою. Я оновив .edmx з бази даних, після чого виняток зник.



0

Також боровся з цією помилкою, і на підставі теми тут, і ця відповідь змогла з’ясувати фрагмент для копіювання / вставки без необхідності з'ясувати, що потрібно імпортувати (відмінно для початківців C #), код нижче:

try
{
  context.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
  foreach (var entityValidationErrors in ex.EntityValidationErrors)
  {
    foreach (var validationError in entityValidationErrors.ValidationErrors)
    {
      System.Diagnostics.Debug.WriteLine("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
    }
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.