web-dev-qa-db-fra.com

La validation a échoué pour une ou plusieurs entités. Voir la propriété 'EntityValidationErrors' pour plus de détails

Je rencontre cette erreur lors de l'ensemencement de ma base de données avec un code d'abord.

La validation a échoué pour une ou plusieurs entités. Voir la propriété 'EntityValidationErrors' pour plus de détails.

Pour être honnête, je ne sais pas comment vérifier le contenu des erreurs de validation. Visual Studio me montre que c'est un tableau avec 8 objets, donc 8 erreurs de validation.

Cela fonctionnait avec mon modèle précédent, mais j'ai apporté quelques modifications que j'explique ci-dessous:

  • J'ai eu un enum appelé Status, je l'ai changé en une classe appelée Status
  • J'ai changé la classe ApplicantsPositionHistory pour avoir 2 clés étrangères sur la même table

Excusez-moi pour le code long, mais je dois tout coller. L'exception est levée dans la dernière ligne du code suivant.

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
        }
    }
}
710
Luis Valencia

Pour être honnête, je ne sais pas comment vérifier le contenu des erreurs de validation. Visual Studio me montre que c'est un tableau avec 8 objets, donc 8 erreurs de validation.

En fait, vous devriez voir les erreurs si vous explorez ce tableau dans Visual studio lors du débogage. Mais vous pouvez également intercepter l'exception, puis écrire les erreurs dans un magasin de journalisation ou la console:

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 est une collection qui représente les entités qui n'ont pas pu être validées, et la collection interne ValidationErrors par entité est une liste d'erreurs au niveau de la propriété.

Ces messages de validation sont généralement assez utiles pour trouver la source du problème. 

Modifier

Quelques légères améliorations:

La valeur de la propriété incriminée peut être incluse dans la boucle interne de la manière suivante:

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

Bien que le débogage Debug.Write puisse être préférable à Console.WriteLine car cela fonctionne dans tout type d’applications, pas seulement les applications en console (merci à @Bart pour sa note dans les commentaires ci-dessous).

Pour les applications Web en production qui utilisent Elmah pour la journalisation des exceptions, il s’est avéré très utile pour moi de créer une exception personnalisée et d’écraser SaveChanges afin de lancer cette nouvelle exception.

Le type d'exception personnalisée ressemble à ceci:

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

Et SaveChanges peut être écrasé de la manière suivante:

public class MyContext : DbContext
{
    // ...

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

Quelques remarques:

  • L'écran d'erreur jaune affiché par Elmah dans l'interface Web ou dans les e-mails envoyés (si vous l'avez configuré) affiche désormais les détails de la validation directement en haut du message.

  • Le remplacement de la propriété Message dans l'exception personnalisée au lieu du remplacement de ToString() a pour avantage que l'écran standard "Écran de mort jaune (YSOD) ASP.NET" affiche également ce message. Contrairement à Elmah, YSOD n'utilise apparemment pas ToString(), mais les deux affichent la propriété Message.

  • Le fait d'encapsuler la DbEntityValidationException d'origine en tant qu'exception interne garantit que la trace de pile d'origine sera toujours disponible et s'affiche dans Elmah et YSOD.

  • En définissant un point d'arrêt sur la ligne throw newException;, vous pouvez simplement inspecter la propriété newException.Message en tant que texte au lieu d'explorer les collections de validation, ce qui est un peu gênant et ne semble pas fonctionner facilement pour tout le monde (voir les commentaires ci-dessous).

1127
Slauma

Vous pouvez le faire à partir de Visual Studio pendant le débogage sans écrire de code, pas même un bloc catch.

Ajoutez simplement une montre avec le nom:

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

L'expression de contrôle $exception affiche toute exception levée dans le contexte actuel, même si elle n'a pas été interceptée et affectée à une variable.

Basé sur http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/

410
yoel halb

Cela pourrait effectivement le faire sans avoir à écrire du code: 

Dans votre bloc catch, ajoutez un point d'arrêt à la ligne de code suivante:

catch (Exception exception)
{

}

Maintenant, si vous passez la souris sur exception ou si vous l'ajoutez à la Watch, puis naviguez dans les détails de l'exception comme indiqué ci-dessous; vous verrez quelle (s) colonne (s) est/sont à l'origine du problème car cette erreur se produit généralement lorsqu'une contrainte de table est violée.

enter image description here

Grande image

88
t_plusplus

Voici comment vérifier le contenu de EntityValidationErrors dans Visual Studio (sans écrire de code supplémentaire), c'est-à-dire pendant Debugging dans IDE.

Le problème?

Vous avez raison, le menu contextuel View Details du débogueur Visual Studio n'affiche pas les erreurs réelles dans la collection EntityValidationErrors

 enter image description here

La solution!

Ajoutez simplement l'expression suivante dans une fenêtre Quick Watch et cliquez sur Reevaluate.

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

Dans mon cas, voyez comment je peux développer la ValidationErrorsList dans la collection EntityValidationErrors 

 enter image description here

Références:mattrandle.me blog post , @ yoel's answer

42
Shiva

Pour voir rapidement la première erreur sans même ajouter de montre, vous pouvez la coller dans la fenêtre Immédiate:

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

Pour tous ceux qui travaillent dans 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
14
nghiavt

Pendant que vous êtes en mode débogage dans le bloc catch {...}, ouvrez la fenêtre "QuickWatch" (ctrl+alt+q) et coller dedans:

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

ou:

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

Si vous n'êtes pas dans un try/catch ou n'avez pas accès à l'objet exception.

Cela vous permettra d’avancer dans l’arborescence ValidationErrors. C'est le moyen le plus simple que j'ai trouvé d'obtenir un aperçu instantané de ces erreurs.

11
GONeale

Si vous attrapez simplement une exception générique, il peut être avantageux de la convertir en/ DbEntityValidationException . Ce type d’exception a une propriété Erreurs de validation et, en continuant de s’y étendre, vous trouverez tous les problèmes.

Par exemple, si vous mettez un point d'arrêt dans la capture, vous pouvez lancer ce qui suit dans une montre:

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

Un exemple d'erreur est si un champ n'autorise pas les valeurs NULL et que vous avez une chaîne NULL, vous verrez qu'il indique que le champ est obligatoire.

10
Greg

En débogage, vous pouvez entrer ceci dans votre zone de saisie de l'évaluateur d'expression QuickWatch:

context.GetValidationErrors()
9
silverfox1948

il suffit de vérifier la longueur du champ de votre table de base de données. Votre texte d'entrée est supérieur à la longueur du type de données du champ de colonne

8
Hardeep Singh

Je devais écrire ceci dans la fenêtre Immédiate: 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]

afin de plonger dans l'erreur exacte!

7
Nour Sabouny

Réponse de @ Slauma et suggestion de Milton Nous avons étendu la méthode de sauvegarde personnalisée de notre classe de base avec un test/intercepteur qui gérera (et enregistrera donc dans notre journal des erreurs!) Ce type d'exceptions.

// 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);
    }
}
6
jocull

La réponse de @Slauma est vraiment excellente, mais j'ai constaté que cela ne fonctionnait pas lorsqu'une propriété ComplexType n'était pas valide. 

Par exemple, supposons que vous ayez une propriété Phone du type complexe PhoneNumber. Si la propriété AreaCode n'est pas valide, le nom de la propriété dans ve.PropertyNames est "Phone.AreaCode". Cela provoque l'appel à eve.Entry.CurrentValues<object>(ve.PropertyName) à échouer. 

Pour résoudre ce problème, vous pouvez fractionner le nom de la propriété à chaque ., puis effectuer une nouvelle analyse dans le tableau résultant des noms de propriété. Enfin, lorsque vous arrivez en bas de la chaîne, vous pouvez simplement renvoyer la valeur de la propriété.

Ci-dessous, la classe FormattedDbEntityValidationException de @ Slauma, qui prend en charge ComplexTypes.

Prendre plaisir!

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

Notez que Entity.GetType().BaseType.Name donne le nom du type que vous avez spécifié, pas celui avec tous les chiffres hexadécimaux dans son nom.

6
Eric Nelson

En utilisant la réponse de @Slauma, j'ai créé un extrait de code (un encadré avec un extrait) pour une meilleure utilisation.

<?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>
6
Phoenix_uy

Attrapez l'exception dans un catch try, puis observez rapidement ou ctrl + d & ctrl + q et vous pourrez explorer jusqu'à EntityValidationErrors.

5
Brandon.Staley

Ce que j'ai trouvé ... quand j'ai eu l'erreur 'EntityValidationErrors' est que .... j'ai un champ dans ma base de données 'db1' dans la table 'tbladdress' comme 'adresse1' qui a la taille 100 (c'est-à-dire l'adresse varchar (100) null) et que je transmettais une valeur supérieure à 100 caractères..et cela entraînait une erreur lors de la sauvegarde des données dans la base de données ....

Vous devez donc vérifier les données que vous transmettez sur le terrain.

4

Je viens de jeter mes deux cents dans ...

Dans mon fichier dbConfiguration.cs, j'aime bien insérer ma méthode context.SaveChanges () dans un fichier try/catch et produire un fichier texte en sortie qui me permet de lire clairement les erreurs, et ce code les rencontrer plus d'une erreur à des moments différents!

        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;
        }
4
IfElseTryCatch

Comme mentionné dans d'autres articles, attrapez simplement l'exception dans la classe DbEntityValidationException .

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

Cela fonctionne pour moi.

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

Placez un point d'arrêt sur l'instruction if . Ensuite, vous pouvez vérifier modelState dans les fenêtres de débogage. Sur chaque valeur, vous pouvez voir s'il y a une erreur et même le message d'erreur. C'est ça… .. Quand vous n'en avez plus besoin, supprimez ou commentez la ligne.

J'espère que cela aidera.

Si on me le demande, je peux fournir une capture d'écran détaillée dans la fenêtre de débogage.

3
AngelDown

J'ai fait face à cette erreur avant 

quand j'ai essayé de mettre à jour un champ spécifique de mon modèle dans le cadre d'entité

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

et selon les réponses ci-dessus 

J'ai trouvé le message de validation The SignerName field is required.

qui pointe vers le champ dans mon modèle 

et quand j'ai vérifié mon schéma de base de données, j'ai trouvé 

 enter image description here

donc hors coure ValidationException a le droit de soulever 

et selon ce champ, je veux que ce soit nul, (je ne sais pas comment je l'ai foiré)

donc j'ai changé ce champ pour autoriser Null, et par cela mon code ne me donnera plus cette erreur 

alors cette erreur peut-être s'est produite si vous invalidez l'intégrité de vos données de votre base de données 

2
Basheer AL-MOMANI

S'il vous plaît vérifier la valeur des champs que vous passez, sont valides et selon les champs de base de données. Par exemple, le nombre de caractères transmis dans un champ particulier est inférieur à celui défini dans le champ table de la base de données.

2
arun tiwari

Si vous utilisezIISavec Authentification Windows et Entity Framework , veillez à utiliser authorize.

J'ai essayé de POST sans autorisation et cela n'a pas fonctionné. Cette erreur s'est produite sur db.SaveChangesAsync(); alors que tous les autres verbes GET et DELETE fonctionnaient.

Mais quand j'ai ajouté AuthorizeAttribute comme annotation, cela a fonctionné.

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

Vérifiez si vous avez la contrainte Not Null dans les colonnes de votre table et si vous ne transmettez pas la valeur de cette colonne lors des opérations d'insertion/de mise à jour .

0
s Jagathish

J'ai aussi fait face au même problème. J'ai mis à jour mon fichier .edmx de la base de données après la disparition de l'exception. 

0
HariChintha

Voici une autre façon de le faire au lieu d'utiliser des boucles foreach pour regarder à l'intérieur d'EntityValidationErrors. Bien sûr, vous pouvez formater le message à votre guise:

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;
    }
0
Quantum_Joe

Dans mon cas, c'était parce que la longueur du champ de la base de données était inférieure à celle du champ d'entrée.

table de base de données

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

Mon entrée

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

la valeur de Usernamelength est 5 qui est lessthan 6

... cela peut aider quelqu'un

0
Qwerty

Cette erreur se produit principalement à cause de la taille du champ . CHECK de toutes les tailles de champs d'une table de base de données.

0
Alexander Zaldostanov