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:
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
}
}
}
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).
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/
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.
Voici comment vérifier le contenu de EntityValidationErrors dans Visual Studio (sans écrire de code supplémentaire), c'est-à-dire pendant Debugging dans IDE.
Vous avez raison, le menu contextuel View Details du débogueur Visual Studio n'affiche pas les erreurs réelles dans la collection EntityValidationErrors
.
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 ValidationErrors
List
dans la collection EntityValidationErrors
Références:mattrandle.me blog post , @ yoel's answer
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()
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
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.
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.
En débogage, vous pouvez entrer ceci dans votre zone de saisie de l'évaluateur d'expression QuickWatch:
context.GetValidationErrors()
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
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!
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);
}
}
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());
}
}
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.
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>
Attrapez l'exception dans un catch try, puis observez rapidement ou ctrl + d & ctrl + q et vous pourrez explorer jusqu'à EntityValidationErrors.
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.
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;
}
Comme mentionné dans d'autres articles, attrapez simplement l'exception dans la classe DbEntityValidationException .
try
{
....
}
catch(DbEntityValidationException ex)
{
....
}
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.
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é
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
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.
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(...){
....
}
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 .
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.
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;
}
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 Username
length
est 5 qui est lessthan
6
... cela peut aider quelqu'un
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.