it-swarm.com.de

Die Überprüfung für eine oder mehrere Entitäten ist fehlgeschlagen. Weitere Informationen finden Sie unter der Eigenschaft 'EntityValidationErrors'

Ich habe diesen Fehler, wenn ich meine Datenbank mit dem Code-First-Ansatz aussehe.

Die Überprüfung für eine oder mehrere Entitäten ist fehlgeschlagen. Weitere Informationen finden Sie unter der Eigenschaft 'EntityValidationErrors'.

Um ehrlich zu sein, weiß ich nicht, wie ich den Inhalt der Validierungsfehler überprüfen kann. Visual Studio zeigt mir, dass es sich um ein Array mit 8 Objekten handelt, also um 8 Validierungsfehler.

Dies funktionierte mit meinem vorherigen Modell, aber ich habe einige Änderungen vorgenommen, die ich im Folgenden erkläre:

  • Ich hatte ein Enum namens Status, ich habe es in eine Klasse namens Status geändert
  • Ich habe die Klasse ApplicantsPositionHistory geändert, um 2 Fremdschlüssel in derselben Tabelle zu haben

Entschuldigen Sie mich für den langen Code, aber ich muss alles einfügen. Die Ausnahme wird in der letzten Zeile des folgenden Codes ausgelöst.

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

Um ehrlich zu sein, weiß ich nicht, wie ich den Inhalt der Validierungsfehler überprüfen kann. Visual Studio zeigt mir, dass es sich um ein Array mit 8 Objekten handelt, also um 8 Validierungsfehler.

Eigentlich sollten Sie die Fehler sehen, wenn Sie während des Debugging in Visual Studio einen Drill-Vorgang durchführen. Sie können jedoch auch die Ausnahme abfangen und die Fehler dann in einen Protokollspeicher oder die Konsole schreiben:

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 ist eine Auflistung, die die Entitäten darstellt, die nicht erfolgreich überprüft werden konnten, und die innere Auflistung ValidationErrors pro Entität ist eine Liste von Fehlern auf Eigenschaftsebene.

Diese Überprüfungsmeldungen sind in der Regel hilfreich, um die Ursache des Problems zu finden. 

Bearbeiten

Einige kleine Verbesserungen:

Der value der verletzenden Eigenschaft kann wie folgt in die innere Schleife eingefügt werden:

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

Während das Debuggen von Debug.Write dem von Console.WriteLine vorzuziehen ist, ist dies in allen Arten von Anwendungen möglich, nicht nur in Konsolenanwendungen (dank @Bart für seinen Hinweis in den Kommentaren unten).

Für Webanwendungen, die sich in der Produktion befinden und Elmah für die Ausnahmelogistik verwenden, war es für mich sehr nützlich, eine benutzerdefinierte Ausnahme zu erstellen und SaveChanges zu überschreiben, um diese neue Ausnahme auszulösen.

Der benutzerdefinierte Ausnahmetyp sieht folgendermaßen aus:

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

Und SaveChanges kann folgendermaßen überschrieben werden:

public class MyContext : DbContext
{
    // ...

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

Ein paar Anmerkungen:

  • Der gelbe Fehlerbildschirm, den Elmah in der Weboberfläche oder in den gesendeten E-Mails anzeigt (sofern Sie dies konfiguriert haben) zeigt jetzt die Validierungsdetails direkt oben in der Nachricht an.

  • Das Überschreiben der Message-Eigenschaft in der benutzerdefinierten Ausnahme anstelle des Überschreibens von ToString() hat den Vorteil, dass auch die Standard-ASP.NET-Anzeige "Yellow Screen of Death (YSOD)" diese Meldung anzeigt. Im Gegensatz zu Elmah verwendet das YSOD anscheinend nicht ToString(), sondern beide zeigen die Message-Eigenschaft an.

  • Durch das Umschließen der ursprünglichen DbEntityValidationException als innere Ausnahme wird sichergestellt, dass die ursprüngliche Stack-Ablaufverfolgung weiterhin verfügbar ist und in Elmah und YSOD angezeigt wird.

  • Durch das Festlegen eines Haltepunkts in der Zeile throw newException; können Sie die newException.Message-Eigenschaft einfach als Text überprüfen, anstatt in die Validierungssammlungen zu bohren.

1127
Slauma

Sie können dies während des Debugging von Visual Studio aus tun, ohne Code schreiben zu müssen, nicht einmal einen catch-Block.

Fügen Sie einfach eine Uhr mit dem Namen hinzu:

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

Der Überwachungsausdruck $exception zeigt jede im aktuellen Kontext geworfene Ausnahme an, auch wenn sie nicht abgefangen und einer Variablen zugewiesen wurde.

Basierend auf http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/

410
yoel halb

Das könnte es tatsächlich tun, ohne Code schreiben zu müssen: 

Fügen Sie in Ihrem catch-Block einen Haltepunkt in der folgenden Codezeile ein:

catch (Exception exception)
{

}

Wenn Sie sich nun auf exception bewegen oder der Watch hinzufügen, gehen Sie wie unten gezeigt zu den Ausnahmedetails. Sie werden sehen, welche Spalte (n) das Problem verursacht, da dieser Fehler normalerweise auftritt, wenn eine Tabelleneinschränkung verletzt wird.

enter image description here

Großes Bild

88
t_plusplus

So können Sie den Inhalt von EntityValidationErrors in Visual Studio überprüfen (ohne zusätzlichen Code zu schreiben), d. H. Während Debugging in IDE.

Das Problem?

Sie haben Recht, das View Details Popup des Visual Studio-Debuggers zeigt nicht die tatsächlichen Fehler in der EntityValidationErrors-Auflistung an. 

 enter image description here

Die Lösung!

Fügen Sie einfach den folgenden Ausdruck in ein Quick Watch Fenster ein und klicken Sie auf Neubewertung.

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

In meinem Fall sehen Sie, wie ich in der Variablen ValidationErrors in die Variable ListEntityValidationErrors erweitern kann 

 enter image description here

Referenzen:mattrandle.me Blogbeitrag , @yoels Antwort

42
Shiva

Um schnell den ersten Fehler zu sehen, ohne eine Uhr hinzuzufügen, können Sie diese in das Direktfenster einfügen:

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

Für alle, die in VB.NET arbeiten

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

Öffnen Sie im Debug-Modus des Blocks catch {...} das Fenster "QuickWatch" (ctrl+alt+q) und dort einfügen:

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

oder:

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

Wenn Sie sich nicht in einem Try/Catch befinden oder keinen Zugriff auf das Ausnahmeobjekt haben.

Auf diese Weise können Sie einen Drilldown in den Baum ValidationErrors durchführen. Es ist der einfachste Weg, einen sofortigen Einblick in diese Fehler zu bekommen.

11
GONeale

Wenn Sie einfach eine generische Ausnahme abfangen, kann es von Vorteil sein, diese als DbEntityValidationException umzusetzen. Dieser Ausnahmetyp hat die Eigenschaft "Überprüfungsfehler". Wenn Sie Ihren Weg in diese Bereiche erweitern, werden Sie alle Probleme feststellen.

Wenn Sie zum Beispiel einen Haltepunkt in den Fang setzen, können Sie Folgendes in eine Uhr werfen:

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

Ein Beispiel für einen Fehler ist Wenn ein Feld keine NULL-Werte zulässt und Sie eine NULL-Zeichenfolge haben, sehen Sie, dass das Feld erforderlich ist.

10
Greg

In Debug können Sie dies in Ihr Eingabefeld für den QuickWatch-Ausdrucksauswerter eingeben:

context.GetValidationErrors()
9
silverfox1948

Überprüfen Sie einfach die Länge Ihrer Datenbanktabelle. Ihr Eingabetext ist größer als die Länge der Länge des Spaltenfelddatentyps

8
Hardeep Singh

Ich musste dies im Direktfenster schreiben: 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]

um tief in den genauen fehler zu geraten!

7
Nour Sabouny

Antwort von Per @ Slauma und @ Miltons Vorschlag Ich habe die benutzerdefinierte Save-Methode unserer Basisklasse um ein Try/Catch-Verfahren erweitert, mit dem diese Art von Ausnahmen behandelt werden (und somit unser Fehlerprotokoll protokolliert wird).

// 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

Die Antwort von @Slauma ist wirklich großartig, aber ich fand heraus, dass es nicht funktionierte, wenn eine ComplexType-Eigenschaft ungültig war. 

Angenommen, Sie haben eine Eigenschaft Phone des komplexen Typs PhoneNumber. Wenn die AreaCode-Eigenschaft ungültig ist, lautet der Eigenschaftsname in ve.PropertyNames "Phone.AreaCode". Dadurch schlägt der Aufruf von eve.Entry.CurrentValues<object>(ve.PropertyName) fehl. 

Um dies zu beheben, können Sie den Eigenschaftennamen an jedem . aufteilen und dann das resultierende Array mit den Eigenschaftennamen erneut aufrufen. Wenn Sie am Ende der Kette angekommen sind, können Sie den Wert der Eigenschaft einfach zurückgeben.

Unten ist die @ Slauma-Klasse FormattedDbEntityValidationException mit Unterstützung für ComplexTypes.

Genießen!

[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

Beachten Sie, dass Entity.GetType().BaseType.Name den von Ihnen angegebenen Typnamen angibt, nicht den Namen mit allen Hex-Ziffern im Namen.

6
Eric Nelson

Mit der Antwort von @Slauma habe ich ein Code-Snippet (ein Surround mit Snippet) zur besseren Verwendung erstellt.

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

Fangen Sie die Ausnahme in einem Try-Catch und dann mit Quick Watch oder Ctrl + D & Ctrl + Q ab, und Sie können einen Drilldown zu den EntityValidationErrors durchführen.

5
Brandon.Staley

Was ich gefunden habe ... als ich den 'EntityValidationErrors'-Fehler bekam, ist Folgendes: Ich habe ein Feld in meiner Datenbank' db1 'in der Tabelle' tbladdress 'als' address1 'mit der Größe 100 (dh Adresse varchar (100)). null) und ich habe einen Wert von mehr als 100 Zeichen übergeben ... und dies führte zu Fehlern beim Speichern von Daten in der Datenbank ....

Sie müssen also die Daten überprüfen, die Sie an das Feld übergeben.

Werfen nur meine zwei Cent in ...

In meiner dbConfiguration.cs möchte ich meine context.SaveChanges () -Methode in eine try/catch -Datei packen und eine Ausgabetextdatei erstellen, die es mir ermöglicht, die Fehler klar zu lesen, und dieser Code gibt ihnen auch Zeitstempel - praktisch, wenn Sie dies tun stoßen Sie zu verschiedenen Zeiten auf mehr als einen Fehler!

        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

Wie in anderen Beiträgen erwähnt, fangen Sie einfach die Ausnahme in der Klasse DbEntityValidationException . Ab.

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

Das funktioniert für mich.

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

Setzen Sie einen Haltepunkt auf if-Anweisung . Dann können Sie modelState in Debug-Fenstern überprüfen. Bei jedem Wert können Sie sehen, ob ein Fehler vorliegt, und sogar die Fehlermeldung. Das ist es ... Wenn Sie es nicht mehr brauchen, löschen oder kommentieren Sie einfach die Zeile.

Ich hoffe das wird helfen.

Wenn Sie dazu aufgefordert werden, kann ich einen detaillierten Screenshot im Debug-Fenster bereitstellen.

3
AngelDown

Ich habe diesen Fehler schon einmal gesehen 

wenn ich versuchte, bestimmtes Feld in meinem Modell im Entity-Rahmen zu aktualisieren

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

und entsprechend den obigen Antworten 

Ich habe die Bestätigungsnachricht The SignerName field is required. gefunden.

was auf ein Feld in meinem Modell zeigt 

und als ich mein Datenbankschema überprüfte, fand ich 

enter image description here

also hat ValidationException das Recht, zu erhöhen 

und nach diesem Feld möchte ich, dass es nullbar ist, (ich weiß nicht, wie ich es vermasselt habe)

also habe ich dieses Feld geändert, um Null zuzulassen, und mein Code gibt mir diesen Fehler nicht mehr 

dieser Fehler tritt möglicherweise auf, wenn Sie Ihre Datenintegrität Ihrer Datenbank ungültig machen 

2

Bitte überprüfen Sie den Feldwert, den Sie übergeben, gültig sind und den Datenbankfeldern entsprechen. Beispielsweise ist die Anzahl der in einem bestimmten Feld übergebenen Zeichen geringer als die im Feld der Datenbanktabelle definierten Zeichen.

2
arun tiwari

Wenn SieISISmit Windows Authentication und Entity Framework verwenden, müssen Sie unbedingt authorize verwenden.

Ich habe versucht, POST ohne autorisieren zu lassen, und es hat nicht funktioniert, und diese Fehlermeldung wurde bei db.SaveChangesAsync(); angezeigt, während alle anderen Verben GET und DELETE funktionieren.

Als ich AuthorizeAttribute als Anmerkung hinzufügte, funktionierte es.

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

Prüfen Sie, ob Sie in Ihren Tabellenspalten eine Not Null-Einschränkung haben, und Sie übergeben den Wert für diese Spalte nicht, wenn Sie Einfüge-/Aktualisierungsvorgänge durchführen.

0
s Jagathish

Ich stand auch vor dem gleichen Problem. Ich habe meine .edmx aus der Datenbank aktualisiert, nachdem die Ausnahme verschwunden ist. 

0
HariChintha

Es gibt eine andere Möglichkeit, dies zu tun, anstatt foreach-Schleifen für den Blick in EntityValidationErrors zu verwenden. Natürlich können Sie die Nachricht nach Ihren Wünschen formatieren:

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

In meinem Fall lag es daran, dass die Länge des Datenbankfeldes geringer ist als die Länge des Eingabefeldes.

Datenbanktabelle

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

Meine Eingabe

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

der Wert für Usernamelength ist 5 was lessthan 6 ist

... das kann jemandem helfen

0
Qwerty

Dieser Fehler tritt hauptsächlich aufgrund der Feldgröße auf. _. Überprüfen Sie alle Feldgrößen in einer Datenbanktabelle.